From eb4e0a0fe7933ad134ffb6560bb15733e4be32db Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Tue, 25 Aug 2026 15:34:29 -0400 Subject: [PATCH 01/10] chore: move gitops promoter stuff downstream Signed-off-by: Christopher Coco --- bundle/manifests/argoproj.io_argocds.yaml | 274 +++ ...gitops-operator.clusterserviceversion.yaml | 2 +- config/crd/bases/argoproj.io_argocds.yaml | 274 +++ ...oter.argoproj.io_argocdcommitstatuses.yaml | 318 +++ ...er.argoproj.io_changetransferpolicies.yaml | 1352 +++++++++++ ...moter.argoproj.io_clusterscmproviders.yaml | 259 +++ .../promoter.argoproj.io_commitstatuses.yaml | 226 ++ ....argoproj.io_controllerconfigurations.yaml | 2072 +++++++++++++++++ ...romoter.argoproj.io_gitcommitstatuses.yaml | 330 +++ .../promoter.argoproj.io_gitrepositories.yaml | 297 +++ ...moter.argoproj.io_promotionstrategies.yaml | 1496 ++++++++++++ .../promoter.argoproj.io_pullrequests.yaml | 309 +++ .../promoter.argoproj.io_revertcommits.yaml | 54 + ...r.argoproj.io_scheduledcommitstatuses.yaml | 452 ++++ .../promoter.argoproj.io_scmproviders.yaml | 258 ++ ...moter.argoproj.io_timedcommitstatuses.yaml | 240 ++ ....argoproj.io_webrequestcommitstatuses.yaml | 856 +++++++ ...gitops-operator.clusterserviceversion.yaml | 79 + go.mod | 167 +- go.sum | 250 +- .../e2e/ginkgo/fixture/agent/fixture.go | 87 +- .../e2e/ginkgo/fixture/certutil/fixture.go | 84 + .../e2e/ginkgo/fixture/promoter/fixture.go | 191 ++ .../1-134_validate_gitops_promoter_test.go | 479 ++++ 24 files changed, 10120 insertions(+), 286 deletions(-) create mode 100644 config/crd/bases/promoter.argoproj.io_argocdcommitstatuses.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_changetransferpolicies.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_clusterscmproviders.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_commitstatuses.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_controllerconfigurations.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_gitcommitstatuses.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_gitrepositories.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_promotionstrategies.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_pullrequests.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_revertcommits.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_scheduledcommitstatuses.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_scmproviders.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_timedcommitstatuses.yaml create mode 100644 config/crd/bases/promoter.argoproj.io_webrequestcommitstatuses.yaml create mode 100644 test/openshift/e2e/ginkgo/fixture/certutil/fixture.go create mode 100644 test/openshift/e2e/ginkgo/fixture/promoter/fixture.go create mode 100644 test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index 3bcfe8ea0b6..dc6d750f00e 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -22725,6 +22725,280 @@ spec: required: - enabled type: object + promoter: + description: Promoter defines the spec for the GitOps Promoter component + properties: + apiserver: + description: APIServer defines the configuration for the promoter's + API server + properties: + enabled: + description: Enabled defines whether or not the API server + should be deployed or not (will default to true if the promoter + is enabled) + type: boolean + tls: + description: TLS defines the TLS settings for the API server + properties: + caSecretKey: + description: CABundleSecretKey is the name of the key + that holds the CA bundle for the API Server's API Service + (defaults to "ca.crt") + type: string + caSecretName: + description: CABundleSecretName is the name of the secret + holding the CA bundle for the API Server's API Service + type: string + certSecretName: + description: CertSecretName is the name of the secret + holding the TLS cert to use for the API Server + type: string + type: object + type: object + argoCDUIExtensionEnabled: + description: ArgoCDUIExtensionEnabled defines whether the Argo + CD UI extension is enabled + type: boolean + enabled: + description: Enabled defines whether gitops promoter controller + should be deployed or not (will default to being disabled) + type: boolean + env: + description: Env lets you specify the environment variables for + the pods that run the controller + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + 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: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + 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 + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + 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 + x-kubernetes-map-type: atomic + 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: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is the image to be used for the GitOps Promoter + type: string + resources: + description: Resources defines the compute resources that are + required for the pods running the controller + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + 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 + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + 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 + webhook: + description: Webhook defines the configuration for the Promoter's + Controller Webhook + properties: + enabled: + description: Enabled defines whether the webhook is enabled + for the Promoter's controller (defaults to being disabled) + type: boolean + serviceType: + description: ServiceType defines what service type the webhook + service will be. If none is provided defaults to ClusterIP + type: string + type: object + type: object rbac: description: RBAC defines the RBAC configuration for Argo CD. properties: diff --git a/bundle/manifests/gitops-operator.clusterserviceversion.yaml b/bundle/manifests/gitops-operator.clusterserviceversion.yaml index e23fba14211..72bfb15b3f6 100644 --- a/bundle/manifests/gitops-operator.clusterserviceversion.yaml +++ b/bundle/manifests/gitops-operator.clusterserviceversion.yaml @@ -190,7 +190,7 @@ metadata: capabilities: Deep Insights console.openshift.io/plugins: '["gitops-plugin"]' containerImage: quay.io/redhat-developer/gitops-operator - createdAt: "2026-08-13T17:59:24Z" + createdAt: "2026-08-25T18:47:12Z" description: Enables teams to adopt GitOps principles for managing cluster configurations and application delivery across hybrid multi-cluster Kubernetes environments. features.operators.openshift.io/disconnected: "true" diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index abdf2666c4d..40fe001b11d 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -22714,6 +22714,280 @@ spec: required: - enabled type: object + promoter: + description: Promoter defines the spec for the GitOps Promoter component + properties: + apiserver: + description: APIServer defines the configuration for the promoter's + API server + properties: + enabled: + description: Enabled defines whether or not the API server + should be deployed or not (will default to true if the promoter + is enabled) + type: boolean + tls: + description: TLS defines the TLS settings for the API server + properties: + caSecretKey: + description: CABundleSecretKey is the name of the key + that holds the CA bundle for the API Server's API Service + (defaults to "ca.crt") + type: string + caSecretName: + description: CABundleSecretName is the name of the secret + holding the CA bundle for the API Server's API Service + type: string + certSecretName: + description: CertSecretName is the name of the secret + holding the TLS cert to use for the API Server + type: string + type: object + type: object + argoCDUIExtensionEnabled: + description: ArgoCDUIExtensionEnabled defines whether the Argo + CD UI extension is enabled + type: boolean + enabled: + description: Enabled defines whether gitops promoter controller + should be deployed or not (will default to being disabled) + type: boolean + env: + description: Env lets you specify the environment variables for + the pods that run the controller + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: |- + Name of the environment variable. + May consist of any printable ASCII characters except '='. + 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: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + 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 + x-kubernetes-map-type: atomic + fileKeyRef: + description: |- + FileKeyRef selects a key of the env file. + Requires the EnvFiles feature gate to be enabled. + properties: + key: + description: |- + The key within the env file. An invalid key will prevent the pod from starting. + The keys defined within a source may consist of any printable ASCII characters except '='. + During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. + type: string + optional: + default: false + description: |- + Specify whether the file or its key must be defined. If the file or key + does not exist, then the env var is not published. + If optional is set to true and the specified key does not exist, + the environment variable will not be set in the Pod's containers. + + If optional is set to false and the specified key does not exist, + an error will be returned during Pod creation. + type: boolean + path: + description: |- + The path within the volume from which to select the file. + Must be relative and may not contain the '..' path or start with '..'. + type: string + volumeName: + description: The name of the volume mount containing + the env file. + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + 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 + x-kubernetes-map-type: atomic + 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: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is the image to be used for the GitOps Promoter + type: string + resources: + description: Resources defines the compute resources that are + required for the pods running the controller + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This field depends on the + DynamicResourceAllocation feature gate. + + 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 + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + 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 + webhook: + description: Webhook defines the configuration for the Promoter's + Controller Webhook + properties: + enabled: + description: Enabled defines whether the webhook is enabled + for the Promoter's controller (defaults to being disabled) + type: boolean + serviceType: + description: ServiceType defines what service type the webhook + service will be. If none is provided defaults to ClusterIP + type: string + type: object + type: object rbac: description: RBAC defines the RBAC configuration for Argo CD. properties: diff --git a/config/crd/bases/promoter.argoproj.io_argocdcommitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_argocdcommitstatuses.yaml new file mode 100644 index 00000000000..f1401b4f7b7 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_argocdcommitstatuses.yaml @@ -0,0 +1,318 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: argocdcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ArgoCDCommitStatus + listKind: ArgoCDCommitStatusList + plural: argocdcommitstatuses + singular: argocdcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCDCommitStatus is the Schema for the argocdcommitstatuses + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#argocdcommitstatus + 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: ArgoCDCommitStatusSpec defines the desired state of ArgoCDCommitStatus. + properties: + applicationSelector: + description: ApplicationSelector is a label selector that selects + the Argo CD applications to which this commit status applies. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + key: + default: argocd-health + description: |- + Key is the gate name referenced in the PromotionStrategy's activeCommitStatuses. + When omitted, the CRD default is argocd-health. Set Key explicitly, even if you use the CRD default. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + url: + description: URL generates the URL to use in the CommitStatus, for + example a link to the Argo CD UI. + properties: + options: + description: "Options sets options for the template. Options are + described by\nstrings, either a simple string or \"key=value\". + There can be at\nmost one equals sign in an option string. If + the option string\nis unrecognized or otherwise invalid, Option + panics.\n\nKnown options:\n\nmissingkey: Control the behavior + during execution if a map is\nindexed with a key that is not + present in the map.\n\n\t\"missingkey=default\" or \"missingkey=invalid\"\n\t\tThe + default behavior: Do nothing and continue execution.\n\t\tIf + printed, the result of the index operation is the string\n\t\t\"\".\n\t\"missingkey=zero\"\n\t\tThe operation returns + the zero value for the map type's element.\n\t\"missingkey=error\"\n\t\tExecution + stops immediately with an error." + items: + type: string + type: array + template: + description: |- + Template is a go text template and receives .Environment and .ArgoCDCommitStatus variables. A function called urlQueryEscape + is available to escape url query parameters. The template can be configured with options to control the behavior + during execution if a variable is not present. + + Example: + + {{- $baseURL := "https://dev.argocd.local" -}} + {{- if eq .Environment "environment/development" -}} + {{- $baseURL = "https://dev.argocd.local" -}} + {{- else if eq .Environment "environment/staging" -}} + {{- $baseURL = "https://staging.argocd.local" -}} + {{- else if eq .Environment "environment/production" -}} + {{- $baseURL = "https://prod.argocd.local" -}} + {{- end -}} + {{- $labels := "" -}} + {{- range $key, $value := .ArgoCDCommitStatus.Spec.ApplicationSelector.MatchLabels -}} + {{- $labels = printf "%s%s=%s," $labels $key $value -}} + {{- end -}} + {{ printf "%s/applications?labels=%s" $baseURL (urlQueryEscape $labels) }} + type: string + type: object + required: + - applicationSelector + - promotionStrategyRef + type: object + status: + description: ArgoCDCommitStatusStatus defines the observed state of ArgoCDCommitStatus. + properties: + applicationsSelected: + description: |- + ApplicationsSelected represents the Argo CD applications that are selected by the commit status. + This field is sorted by environment (same order as the referenced PromotionStrategy), then namespace, then name. + items: + description: |- + ApplicationsSelected represents the Argo CD applications that are selected by the commit status. The fields in this + struct are all required, since the controller should always fully construct this information. + properties: + clusterName: + description: |- + ClusterName is the name of the cluster that the application manifest is deployed to. An empty string indicates + the local cluster. There is no minimum length, since the local cluster is represented by an empty string. + type: string + environment: + description: Environment is the syncSource.targetBranch of the + Argo CD application (in effect, its environment). + minLength: 1 + type: string + lastTransitionTime: + description: LastTransitionTime is the last time the phase transitioned. + format: date-time + type: string + name: + description: Name is the name of the Argo CD application. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + namespace: + description: Namespace is the namespace of the Argo CD application. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + phase: + description: Phase is the current phase of the commit status. + enum: + - pending + - success + - failure + type: string + sha: + description: |- + Sha is the commit SHA that the application is synced to. + This field is only populated when the application's sync status is Synced. + When the sync status is OutOfSync or Unknown, this field will be empty because + Status.Sync.Revision may contain a branch name instead of a SHA. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^(|[a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - clusterName + - environment + - name + - namespace + - phase + - sha + type: object + type: array + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_changetransferpolicies.yaml b/config/crd/bases/promoter.argoproj.io_changetransferpolicies.yaml new file mode 100644 index 00000000000..7f35333429e --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_changetransferpolicies.yaml @@ -0,0 +1,1352 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: changetransferpolicies.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ChangeTransferPolicy + listKind: ChangeTransferPolicyList + plural: changetransferpolicies + singular: changetransferpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.active.dry.sha + name: Active Dry Sha + type: string + - jsonPath: .status.proposed.dry.sha + name: Proposed Dry Sha + type: string + - jsonPath: .status.proposed.note.drySha + name: Proposed Note Dry Sha + type: string + - jsonPath: .status.pullRequest.state + name: PR State + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ChangeTransferPolicy is the Schema for the changetransferpolicies + API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#changetransferpolicy + 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: ChangeTransferPolicySpec defines the desired state of ChangeTransferPolicy + properties: + activeBranch: + description: |- + ActiveBranch staging hydrated branch + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + activeCommitStatuses: + description: ActiveCommitStatuses lists the statuses to be monitored + on the active branch + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath is an optional repository subpath for this policy's active state. + When set, hydrator metadata is read from /hydrator.metadata. + minLength: 1 + type: string + autoMerge: + default: true + type: boolean + gitRepositoryRef: + description: RepositoryReference what repository to open the PR on. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + proposedBranch: + description: |- + ProposedBranch staging hydrated branch + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + proposedCommitStatuses: + description: ProposedCommitStatuses lists the statuses to be monitored + on the proposed branch + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + pullRequest: + description: |- + PullRequest configures SCM pull request behavior for this change transfer policy. + Copied from the owning PromotionStrategy by the PromotionStrategy controller. + properties: + labels: + description: Labels configures dynamic SCM labels applied to promotion + pull requests. + properties: + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against + ChangeTransferPolicy status and spec. It must return a list of SCM label name strings. + + Available variables: + - Status: ChangeTransferPolicy status (Proposed/Active commit statuses, branch SHAs, etc.) + - Spec: ChangeTransferPolicy spec (ActiveBranch, ProposedBranch, etc.) + - PromotionStrategy: owning PromotionStrategy spec and status when available + + Each returned label name must satisfy the same validation as PullRequest.spec.labels + (non-empty, max 50 characters, no newlines, max 10 labels, unique). + maxLength: 8192 + minLength: 1 + type: string + required: + - expression + type: object + type: object + required: + - activeBranch + - gitRepositoryRef + - proposedBranch + type: object + status: + description: ChangeTransferPolicyStatus defines the observed state of + ChangeTransferPolicy + properties: + active: + description: Active is the state of the active branch. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses that + are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines the + phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the commit + status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is the + commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, which + is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the git note attached + to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit that was + used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that was used + to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that was used + to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located. + type: string + subject: + description: Subject is the subject line of the dry commit + that was used to hydrate the branch. + type: string + type: object + type: object + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + history: + description: |- + History defines the history of promoted changes done by the ChangeTransferPolicy. You can think of + it as a list of PRs merged by GitOps Promoter. It will not include changes that were manually merged. + The history length is hard-coded to be at most 5 entries. This may change in the future. + History is constructed on a best-effort basis and should be used for informational purposes only. + History is in reverse chronological order (newest is first). + items: + description: History describes a particular change that was promoted + by the ChangeTransferPolicy. + properties: + active: + description: Active is the state of the active branch at the + time the PR was merged. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + proposed: + description: Proposed is the state of the proposed branch at + the time the PR was merged. + properties: + commitStatuses: + description: |- + CommitStatuses is a list of commit statuses that were being monitored for this branch. + This contains the state frozen at the moment the PR was merged. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that + was created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: array + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + proposed: + description: Proposed is the state of the proposed branch. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses that + are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines the + phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the commit + status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is the + commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, which + is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the git note attached + to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit that was + used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that was used + to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that was used + to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located. + type: string + subject: + description: Subject is the subject line of the dry commit + that was used to hydrate the branch. + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that was + created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_clusterscmproviders.yaml b/config/crd/bases/promoter.argoproj.io_clusterscmproviders.yaml new file mode 100644 index 00000000000..d9291b77e36 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_clusterscmproviders.yaml @@ -0,0 +1,259 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: clusterscmproviders.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ClusterScmProvider + listKind: ClusterScmProviderList + plural: clusterscmproviders + singular: clusterscmprovider + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterScmProvider is the Schema for the clusterscmproviders + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#clusterscmprovider + 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: ScmProviderSpec defines the desired state of ScmProvider + properties: + azureDevOps: + description: AzureDevOps required configuration for Azure DevOps as + the SCM provider + properties: + domain: + description: Domain is the Azure DevOps domain, such as "dev.azure.com". + If using the default Azure DevOps domain, leave this field empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to dev.azure.com, leave + the field blank + rule: self != "dev.azure.com" + organization: + description: Organization is the Azure DevOps organization name. + maxLength: 50 + minLength: 1 + pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$ + type: string + required: + - organization + type: object + bitbucketCloud: + description: BitbucketCloud required configuration for Bitbucket Cloud + as the SCM provider + type: object + fake: + description: Fake required configuration for Fake as the SCM provider + properties: + domain: + description: Domain is the domain of the fake SCM provider. This + is used for testing purposes. + maxLength: 253 + minLength: 1 + type: string + type: object + forgejo: + description: Forgejo required configuration for Forgejo as the SCM + provider + properties: + domain: + description: |- + Domain is the Forgejo domain, such as "codeberg.org" or "forgejo.mycompany.com". + There is no default domain since Forgejo is not a service like Gitlab or Github. + maxLength: 253 + minLength: 1 + type: string + required: + - domain + type: object + gitea: + description: Gitea required configuration for Gitea as the SCM provider + properties: + domain: + description: |- + Domain is the Gitea domain, such as "gitea.com" or "gitea.mycompany.com". + There is no default domain since Gitea is self-hosted. + minLength: 1 + type: string + required: + - domain + type: object + github: + description: GitHub required configuration for GitHub as the SCM provider + properties: + appID: + description: AppID is the GitHub App ID. + format: int64 + minimum: 0 + type: integer + domain: + description: |- + Domain is the GitHub domain, such as "github.mycompany.com". If using the default GitHub domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to github.com, leave + the field blank + rule: self != "github.com" + installationID: + description: |- + InstallationID is the GitHub App Installation ID. If you want to use this ScmProvider for multiple + GitHub orgs, do not specify this field. The installation ID will be inferred from the repo owner + when needed. + format: int64 + minimum: 0 + type: integer + required: + - appID + type: object + gitlab: + description: GitLab required configuration for GitLab as the SCM provider + properties: + domain: + description: |- + Domain is the GitLab domain, such as "gitlab.mycompany.com". If using the default GitLab domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to gitlab.com, leave + the field blank + rule: self != "gitlab.com" + type: object + secretRef: + description: SecretRef contains the credentials required to auth to + a specific provider + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: ScmProviderStatus defines the observed state of ScmProvider + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_commitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_commitstatuses.yaml new file mode 100644 index 00000000000..223f49ca500 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_commitstatuses.yaml @@ -0,0 +1,226 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: commitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: CommitStatus + listKind: CommitStatusList + plural: commitstatuses + singular: commitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.labels['promoter\.argoproj\.io/commit-status'] + name: Key + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .status.sha + name: Sha + type: string + - jsonPath: .spec.name + name: Name + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + priority: 1 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: CommitStatus is the Schema for the commitstatuses API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#commitstatus + 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: CommitStatusSpec defines the desired state of CommitStatus + properties: + description: + description: |- + Description is a human-readable description of the commit status. + This is shown in the SCM provider (GitHub, GitLab, etc.) as the commit status description. + Use an action-oriented message to convey that the system is actively working. For example, + "Waiting for approval" instead of "Approval pending." + type: string + gitRepositoryRef: + description: ObjectReference is a reference to an object by name. + It is used to refer to objects in the same namespace. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + name: + description: Name is the name of the commit status. + minLength: 1 + type: string + phase: + default: pending + description: Phase is the state of the commit status. This will be + mapped to the appropriate equivalent in the SCM. + enum: + - pending + - success + - failure + type: string + sha: + description: |- + SHA is the commit SHA to set the status on. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + url: + description: Url is a URL that the user can follow to see more details + about the status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - description + - gitRepositoryRef + - name + - phase + - sha + type: object + status: + description: CommitStatusStatus defines the observed state of CommitStatus + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: Id is the unique identifier of the commit status, set + by the SCM + type: string + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + phase: + default: pending + description: Phase is the state of the commit status. This will be + mapped to the appropriate equivalent in the SCM. + enum: + - pending + - success + - failure + - "" + type: string + sha: + description: |- + Sha is the commit SHA that the status is set on. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_controllerconfigurations.yaml b/config/crd/bases/promoter.argoproj.io_controllerconfigurations.yaml new file mode 100644 index 00000000000..c1bf42ad2fd --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_controllerconfigurations.yaml @@ -0,0 +1,2072 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: controllerconfigurations.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ControllerConfiguration + listKind: ControllerConfigurationList + plural: controllerconfigurations + singular: controllerconfiguration + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ControllerConfiguration is the Schema for the controllerconfigurations + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#controllerconfiguration + 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: |- + ControllerConfigurationSpec defines the desired state of ControllerConfiguration. + + This spec contains the global configuration for all controllers in the promoter system. + Each controller has its own configuration section that specifies WorkQueue settings, + rate limiters, and other controller-specific parameters. All fields should be required, + with defaults set in manifests rather than in code. + properties: + argocdCommitStatus: + description: |- + ArgoCDCommitStatus contains the configuration for the ArgoCDCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + watchLocalApplications: + default: true + description: |- + WatchLocalApplications controls whether the controller monitors Argo CD Applications + in the local cluster. When false, the controller will only watch Applications in remote clusters + configured via kubeconfig secrets. This is useful when the Argo CD Application CRD is not installed + in the local cluster or when all Applications are deployed to remote clusters. + type: boolean + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ArgoCDCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - watchLocalApplications + - workQueue + type: object + changeTransferPolicy: + description: |- + ChangeTransferPolicy contains the configuration for the ChangeTransferPolicy controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ChangeTransferPolicy controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + commitStatus: + description: |- + CommitStatus contains the configuration for the CommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the CommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + gitCommitStatus: + description: |- + GitCommitStatus contains the configuration for the GitCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the GitCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + instanceID: + description: |- + InstanceID scopes which Promoter CRs this install reconciles. When set, only resources + labeled promoter.argoproj.io/instance-id with this exact value enter the informer cache. + When unset (nil), only resources without that label are reconciled. There is no mode that + reconciles labeled and unlabeled resources together. Changing this value rebuilds the + informer cache partition: a single-replica install shuts down and restarts automatically; + HA installs (multiple replicas with leader election) require a rolling restart of all pods. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + promotionStrategy: + description: |- + PromotionStrategy contains the configuration for the PromotionStrategy controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the PromotionStrategy controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + pullRequest: + description: |- + PullRequest contains the configuration for the PullRequest controller, + including WorkQueue settings and pull request template configuration. + properties: + template: + description: |- + Template is the template configuration used to generate pull request titles and descriptions. + Uses Go template syntax with Sprig functions available. + properties: + description: + description: |- + Description is the template used to generate the body/description of the pull request. + Uses Go template syntax with Sprig functions available for string manipulation. + type: string + title: + description: |- + Title is the template used to generate the title of the pull request. + Uses Go template syntax with Sprig functions available for string manipulation. + type: string + required: + - description + - title + type: object + workQueue: + description: |- + WorkQueue contains the work queue configuration for the PullRequest controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - template + - workQueue + type: object + scheduledCommitStatus: + description: |- + ScheduledCommitStatus contains the configuration for the ScheduledCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ScheduledCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + timedCommitStatus: + description: |- + TimedCommitStatus contains the configuration for the TimedCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the TimedCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + webRequestCommitStatus: + description: |- + WebRequestCommitStatus contains the configuration for the WebRequestCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the WebRequestCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + required: + - argocdCommitStatus + - changeTransferPolicy + - commitStatus + - gitCommitStatus + - promotionStrategy + - pullRequest + - scheduledCommitStatus + - timedCommitStatus + - webRequestCommitStatus + type: object + status: + description: ControllerConfigurationStatus defines the observed state + of ControllerConfiguration. + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_gitcommitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_gitcommitstatuses.yaml new file mode 100644 index 00000000000..fe19f2a5733 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_gitcommitstatuses.yaml @@ -0,0 +1,330 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: gitcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: GitCommitStatus + listKind: GitCommitStatusList + plural: gitcommitstatuses + singular: gitcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.key + name: Key + type: string + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .spec.target + name: Validates + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + GitCommitStatus is the Schema for the gitcommitstatuses API. + + It validates commits from PromotionStrategy environments using configurable expressions + and creates CommitStatus resources with the validation results. + + Use the Target field to control which commit is validated: + - "active" (default): Validates the currently deployed commit + - "proposed": Validates the incoming commit + + The validation result is always reported on the PROPOSED commit to enable promotion gating, + regardless of which commit was validated. + + Workflow: + 1. Controller reads PromotionStrategy to get ProposedHydratedSha and ActiveHydratedSha + 2. Controller selects SHA to validate based on Target field + 3. Controller fetches commit data (subject, body, author, trailers) for selected SHA + 4. Controller evaluates expression against selected commit data + 5. Controller creates/updates CommitStatus with result attached to PROPOSED SHA + 6. PromotionStrategy checks CommitStatus on PROPOSED SHA before allowing promotion + + Common use cases: + - "Ensure active commit is not a revert before promoting" + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#gitcommitstatus + 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: spec defines the desired state of GitCommitStatus + properties: + description: + description: |- + Description is a human-readable description of this validation that will be shown in the SCM provider + (GitHub, GitLab, etc.) as the commit status description. + If not specified, defaults to empty string. + type: string + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against commit data + for environments in the referenced PromotionStrategy. + The expression must return a boolean value where true indicates the validation passed. + + The commit validated is determined by the Target field: + - "active" (default): Validates the ACTIVE (currently deployed) commit + - "proposed": Validates the PROPOSED commit (what will be promoted) + + The validation result is always reported on the PROPOSED commit to enable promotion gating. + + Use Cases by Mode: + Active mode: State-based gating - validate current environment before allowing promotion + - "Don't promote until active commit has required sign-offs" + - "Verify current deployment meets compliance before next promotion" + - "Ensure active commit is not a revert before promoting" + + Proposed mode: Change-based gating - validate the incoming change itself + - "Don't promote unless new commit follows naming convention" + - "Ensure proposed commit has proper JIRA ticket reference" + - "Require specific author for proposed changes" + + Available variables in the expression context: + - Commit.SHA (string): the commit SHA being validated (active or proposed based on Target) + - Commit.Subject (string): the first line of the commit message + - Commit.Body (string): the commit message body (everything after the subject line) + - Commit.Author (string): commit author email address + - Commit.Trailers (map[string][]string): git trailers parsed from commit message + type: string + key: + description: |- + Key is the unique identifier for this validation rule. + It is used as the commit status key and in status messages. + This key is matched against PromotionStrategy's proposedCommitStatuses or activeCommitStatuses + to determine which environments this validation applies to. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: |- + PromotionStrategyRef is a reference to the promotion strategy that this commit status applies to. + The controller will validate commits from ALL environments in the referenced PromotionStrategy + where this GitCommitStatus.Spec.Key matches an entry in either: + - PromotionStrategy.Spec.ProposedCommitStatuses (applies to all environments), OR + - Environment.ProposedCommitStatuses (applies to specific environment) + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + target: + default: active + description: |- + Target specifies which commit SHA to validate with the expression. + - "active": Validates the currently active/deployed commit (default behavior) + - "proposed": Validates the proposed commit that will be promoted + + The validation result is always reported on the PROPOSED commit (for gating), but this field + controls which commit's data is used in the expression evaluation. + + Examples: + target: "active" - "Don't promote if a revert commit is detected" + target: "proposed" - "Don't promote unless new commit follows naming convention" + enum: + - active + - proposed + type: string + required: + - expression + - key + - promotionStrategyRef + type: object + status: + description: status defines the observed state of GitCommitStatus + properties: + conditions: + description: |- + Conditions represent the latest available observations of the GitCommitStatus's state. + Standard condition types include "Ready" which aggregates the status of all environments. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: |- + Environments holds the validation results for each environment where this validation applies. + Each entry corresponds to an environment from the PromotionStrategy where the Key matches + either global or environment-specific proposedCommitStatuses. + + The controller validates the commit specified by Target ("active" or "proposed") + but the CommitStatus is always reported on the PROPOSED commit for promotion gating. + Each environment entry tracks both the ProposedHydratedSha (where status is reported) and the + ActiveHydratedSha, with TargetedSha indicating which one was actually evaluated. + items: + description: GitCommitStatusEnvironmentStatus defines the observed + validation status for a specific environment. + properties: + activeHydratedSha: + description: |- + ActiveHydratedSha is the currently active (deployed) hydrated commit SHA that was validated. + This comes from the PromotionStrategy's environment status. + The expression is evaluated against THIS commit's data, not the proposed commit. + May be empty if the PromotionStrategy hasn't reconciled yet. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + branch: + description: Branch is the environment branch name being validated. + minLength: 1 + type: string + expressionResult: + description: |- + ExpressionResult contains the boolean result of the expression evaluation. + Only set when the expression successfully evaluates to a boolean. + nil indicates the expression has not yet been evaluated, failed to compile, or failed to evaluate. + type: boolean + phase: + description: |- + Phase represents the current validation state of the commit. + - "pending": validation has not completed, commit data is not yet available, or SHAs are empty + - "success": expression evaluated to true, validation passed + - "failure": expression evaluated to false, validation failed, or expression compilation failed + enum: + - pending + - success + - failure + type: string + proposedHydratedSha: + description: |- + ProposedHydratedSha is the proposed hydrated commit SHA where the validation result is reported. + This comes from the PromotionStrategy's environment status. + The CommitStatus resource is created with this SHA, allowing the PromotionStrategy to gate + promotions based on the validation of the ACTIVE commit. + May be empty if the PromotionStrategy hasn't reconciled yet. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + targetedSha: + description: |- + TargetedSha is the commit SHA that was actually validated by the expression. + This will match either ProposedHydratedSha or ActiveHydratedSha depending on + the Target setting ("proposed" or "active"). + This field clarifies which commit's data was used in the expression evaluation. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - branch + - phase + - proposedHydratedSha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_gitrepositories.yaml b/config/crd/bases/promoter.argoproj.io_gitrepositories.yaml new file mode 100644 index 00000000000..447414476f6 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_gitrepositories.yaml @@ -0,0 +1,297 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: gitrepositories.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: GitRepository + listKind: GitRepositoryList + plural: gitrepositories + singular: gitrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.scmProviderRef.name + name: Provider + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#gitrepository + 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: GitRepositorySpec defines the desired state of GitRepository + properties: + azureDevOps: + description: AzureDevOpsRepo is a repository in Azure DevOps, identified + by its project and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 64 + minLength: 1 + type: string + project: + description: Project is the project name in Azure DevOps. + maxLength: 64 + minLength: 1 + type: string + required: + - name + - project + type: object + bitbucketCloud: + description: BitbucketCloudRepo is a repository in Bitbucket Cloud, + identified by its owner and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 62 + minLength: 1 + pattern: ^[a-zA-Z0-9_.-]+$ + type: string + owner: + description: Owner is the owner of the repository (can be a user + or workspace). + minLength: 1 + pattern: ^[a-zA-Z0-9_-]+$ + type: string + required: + - name + - owner + type: object + fake: + description: FakeRepo is a placeholder for a repository in the fake + SCM provider, used for testing purposes. + properties: + name: + description: Name is the name of the repository. + minLength: 1 + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + forgejo: + description: ForgejoRepo is a repository in Forgejo, identified by + its owner and name. + properties: + name: + description: Name is the name of the repository. + minLength: 1 + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + gitea: + description: GiteaRepo is a repository in Gitea, identified by its + owner and name. + properties: + name: + description: Name is the name of the repository. + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + github: + description: GitHubRepo is a repository in GitHub, identified by its + owner and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 100 + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\.]+$ + type: string + owner: + description: Owner is the owner of the repository, which can be + a user or an organization. + maxLength: 39 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-]*$ + type: string + required: + - name + - owner + type: object + gitlab: + description: GitLabRepo is a repository in GitLab, identified by its + namespace, name, and project ID. + properties: + name: + description: Name is the project slug of the repository. + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\/.]+$ + type: string + namespace: + description: Namespace is the user, group or group with subgroup + (e.g. group/subgroup). + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\/.]+$ + type: string + projectId: + description: ProjectID is the ID of the project in GitLab. + minimum: 0 + type: integer + required: + - name + - namespace + - projectId + type: object + scmProviderRef: + description: ScmProviderObjectReference is a reference to a SCM provider + object. + properties: + kind: + default: ScmProvider + description: Kind is the type of resource being referenced + enum: + - ScmProvider + - ClusterScmProvider + type: string + name: + description: Name is the name of the resource being referenced + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - kind + - name + type: object + required: + - scmProviderRef + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: GitRepositoryStatus defines the observed state of GitRepository + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_promotionstrategies.yaml b/config/crd/bases/promoter.argoproj.io_promotionstrategies.yaml new file mode 100644 index 00000000000..6eeddab2fe9 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_promotionstrategies.yaml @@ -0,0 +1,1496 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: promotionstrategies.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: PromotionStrategy + listKind: PromotionStrategyList + plural: promotionstrategies + singular: promotionstrategy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PromotionStrategy is the Schema for the promotionstrategies API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#promotionstrategy + 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: PromotionStrategySpec defines the desired state of PromotionStrategy + properties: + activeCommitStatuses: + description: |- + ActiveCommitStatuses are commit statuses describing an actively running dry commit. If an active commit status + is failing for an environment, subsequent environments will not deploy the failing commit. + + The commit statuses specified in this field apply to all environments in the promotion sequence. You can also + specify commit statuses for individual environments in the `environments` field. + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath is the default repository subpath for this strategy's active state. + When set, proposed branches are created as -next/. + Individual environments can override this value via their own activePath field. + minLength: 1 + type: string + environments: + description: Environments is the sequence of environments that a dry + commit will be promoted through. + items: + description: Environment defines a single environment in the promotion + sequence. + properties: + activeCommitStatuses: + description: |- + ActiveCommitStatuses are commit statuses describing an actively running dry commit. If an active commit status + is failing for an environment, subsequent environments will not deploy the failing commit. + + The commit statuses specified in this field apply to this environment only. You can also specify commit statuses + for all environments in the `spec.activeCommitStatuses` field. + items: + description: CommitStatusSelector is used to select commit + statuses by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath optionally overrides the strategy-level activePath for this environment. + When set, this environment's CTP uses this path instead of spec.activePath. + minLength: 1 + type: string + autoMerge: + default: true + description: |- + AutoMerge determines whether the dry commit should be automatically merged into the next branch in the sequence. + If false, the dry commit will be proposed but not merged. + type: boolean + branch: + description: |- + Branch is the name of the active branch for the environment. + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + proposedCommitStatuses: + description: |- + ProposedCommitStatuses are commit statuses describing a proposed dry commit, i.e. one that is not yet running + in a live environment. If a proposed commit status is failing for a given environment, the dry commit will not + be promoted to that environment. + + The commit statuses specified in this field apply to this environment only. You can also specify commit statuses + for all environments in the `spec.proposedCommitStatuses` field. + items: + description: CommitStatusSelector is used to select commit + statuses by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - branch + type: object + maxItems: 1000 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + gitRepositoryRef: + description: RepositoryReference indicates what repository to promote + commits in. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + proposedCommitStatuses: + description: |- + ProposedCommitStatuses are commit statuses describing a proposed dry commit, i.e. one that is not yet running + in a live environment. If a proposed commit status is failing for a given environment, the dry commit will not + be promoted to that environment. + + The commit statuses specified in this field apply to all environments in the promotion sequence. You can also + specify commit statuses for individual environments in the `environments` field. + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + pullRequest: + description: PullRequest configures SCM pull request behavior for + all environments in this strategy. + properties: + labels: + description: Labels configures dynamic SCM labels applied to promotion + pull requests. + properties: + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against + ChangeTransferPolicy status and spec. It must return a list of SCM label name strings. + + Available variables: + - Status: ChangeTransferPolicy status (Proposed/Active commit statuses, branch SHAs, etc.) + - Spec: ChangeTransferPolicy spec (ActiveBranch, ProposedBranch, etc.) + - PromotionStrategy: owning PromotionStrategy spec and status when available + + Each returned label name must satisfy the same validation as PullRequest.spec.labels + (non-empty, max 50 characters, no newlines, max 10 labels, unique). + maxLength: 8192 + minLength: 1 + type: string + required: + - expression + type: object + type: object + required: + - environments + - gitRepositoryRef + type: object + status: + description: PromotionStrategyStatus defines the observed state of PromotionStrategy + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment in + the promotion sequence. + items: + description: EnvironmentStatus defines the observed state of an + environment in a PromotionStrategy. + properties: + active: + description: Active is the state of the active branch for the + environment. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + branch: + description: Branch is the name of the active branch for the + environment. + minLength: 1 + type: string + history: + description: |- + History defines the history of promoted changes done by the PromotionStrategy for each environment. + You can think of it as a list of PRs merged by GitOps Promoter. It will not include changes that were + manually merged. The history length is hard-coded to be at most 5 entries. This may change in the future. + History is constructed on a best-effort basis and should be used for informational purposes only. + History is in reverse chronological order (newest is first). + items: + description: History describes a particular change that was + promoted by the ChangeTransferPolicy. + properties: + active: + description: Active is the state of the active branch + at the time the PR was merged. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase + defines the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description + of the commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status + in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which + is the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the + branch, which is the commit that is currently being + worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the + git note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit + that was used to hydrate the branch without + the subject. + type: string + date: + description: Date is the date of the dry commit + that was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + type: string + subject: + description: Subject is the subject line of the + dry commit that was used to hydrate the branch. + type: string + type: object + type: object + proposed: + description: Proposed is the state of the proposed branch + at the time the PR was merged. + properties: + commitStatuses: + description: |- + CommitStatuses is a list of commit statuses that were being monitored for this branch. + This contains the state frozen at the moment the PR was merged. + items: + description: ChangeRequestPolicyCommitStatusPhase + defines the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description + of the commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status + in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + hydrated: + description: Hydrated is the hydrated state of the + branch, which is the commit that is currently being + worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request + that was created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull + request, set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull + request was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: array + lastHealthyDryShas: + description: LastHealthyDryShas is a list of dry commits that + were observed to be healthy in the environment. + items: + description: HealthyDryShas is a list of dry commits that + were observed to be healthy in the environment. + properties: + sha: + description: |- + Sha is the commit SHA of the dry commit that was observed to be healthy. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + time: + description: Time is the time when the proposed commit + for the given dry SHA was merged into the active branch. + format: date-time + type: string + required: + - sha + - time + type: object + type: array + proposed: + description: Proposed is the state of the proposed branch for + the environment. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that + was created for this environment. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + required: + - active + - branch + - proposed + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + required: + - environments + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_pullrequests.yaml b/config/crd/bases/promoter.argoproj.io_pullrequests.yaml new file mode 100644 index 00000000000..f1edd3f1fe2 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_pullrequests.yaml @@ -0,0 +1,309 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: pullrequests.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: PullRequest + listKind: PullRequestList + plural: pullrequests + singular: pullrequest + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.id + name: ID + type: string + - jsonPath: .spec.sourceBranch + name: Source + priority: 1 + type: string + - jsonPath: .spec.targetBranch + name: Target + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.url + name: URL + priority: 1 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PullRequest is the Schema for the pullrequests API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#pullrequest + 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: PullRequestSpec defines the desired state of PullRequest + properties: + commit: + description: Commit contains configuration for how we will merge/squash/etc + the pull request. + properties: + message: + description: Message is the commit message that will be written + for the commit that's made when merging the PR. + type: string + required: + - message + type: object + description: + description: Description is the description body of the pull/merge + request + type: string + gitRepositoryRef: + description: RepositoryReference indicates what repository to open + the PR on. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + labels: + description: |- + Labels is the desired set of SCM pull request labels (not Kubernetes metadata labels). + Written by the ChangeTransferPolicy controller from pullRequest.labels.expression evaluation. + items: + maxLength: 50 + minLength: 1 + pattern: ^[^\n\r\x00]+$ + type: string + maxItems: 10 + type: array + x-kubernetes-list-type: set + mergeSha: + description: |- + MergeSha is the commit SHA that the head branch must match before the PR can be merged. + This prevents a race condition where a PR is merged with a different commit than intended. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + sourceBranch: + description: |- + SourceBranch is the base the git reference that we are merging into Head ---> Base + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: field is immutable + rule: self == oldSelf + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + state: + default: open + description: |- + State of the pull request (closed, merged, or open). Must always be "open" when creating a new pull request. + This value may not be changed to "closed" or "merged" unless the pull request status.id is set. + enum: + - closed + - merged + - open + type: string + targetBranch: + description: |- + TargetBranch is the head the git reference we are merging from Head ---> Base + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: field is immutable + rule: self == oldSelf + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + title: + description: Title is the title of the pull request. + minLength: 1 + type: string + required: + - gitRepositoryRef + - mergeSha + - sourceBranch + - state + - targetBranch + - title + type: object + status: + description: PullRequestStatus defines the observed state of PullRequest + properties: + appliedLabels: + description: AppliedLabels lists SCM labels successfully applied by + gitops-promoter (for sync and retraction). + items: + maxLength: 50 + minLength: 1 + pattern: ^[^\n\r\x00]+$ + type: string + maxItems: 10 + type: array + x-kubernetes-list-type: set + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + resource still desired it open (spec.state is "open"): either it was merged or closed outside the + controller, or it was closed on the SCM because the PullRequest resource was deleted (finalizer) + and a subsequent sync observed it missing. The controller does not distinguish those cases here. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + The PullRequest resource will be deleted after this flag is set when possible, but the status is + preserved in the owning ChangeTransferPolicy to maintain a record. + type: boolean + id: + description: ID the id of the pull request + type: string + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + prCreationTime: + description: PRCreationTime the time the PR was created + format: date-time + type: string + scmSyncedSpecDigest: + description: |- + SCMSyncedSpecDigest fingerprints title and description last successfully synced + to the SCM via provider.Update on an open pull request. + type: string + state: + description: State of the merge request closed/merged/open + enum: + - "" + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + x-kubernetes-validations: + - message: Cannot transition to 'closed' or 'merged' state when status.id + is empty + rule: self.spec.state == 'open' || has(self.status.id) && self.status.id + != "" + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_revertcommits.yaml b/config/crd/bases/promoter.argoproj.io_revertcommits.yaml new file mode 100644 index 00000000000..f8af00263b6 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_revertcommits.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: revertcommits.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: RevertCommit + listKind: RevertCommitList + plural: revertcommits + singular: revertcommit + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: RevertCommit is the Schema for the revertcommits 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: RevertCommitSpec defines the desired state of RevertCommit + properties: + foo: + description: Foo is an example field of RevertCommit. Edit revertcommit_types.go + to remove/update + type: string + type: object + status: + description: RevertCommitStatus defines the observed state of RevertCommit + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_scheduledcommitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_scheduledcommitstatuses.yaml new file mode 100644 index 00000000000..28d3eb6fc21 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_scheduledcommitstatuses.yaml @@ -0,0 +1,452 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: scheduledcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ScheduledCommitStatus + listKind: ScheduledCommitStatusList + plural: scheduledcommitstatuses + singular: scheduledcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScheduledCommitStatus is the Schema for the scheduledcommitstatuses + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#scheduledcommitstatus + 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: spec defines the desired state of ScheduledCommitStatus + properties: + allow: + description: |- + Allow defines global allow windows applied to all listed environments in addition to + per-environment allow windows (OR semantics across all). + items: + description: CronWindow defines a recurring time window using a + cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + environments: + description: |- + Environments defines the list of environments to gate. Only listed environments are gated; + unlisted environments default to success (24/7 open). Each environment inherits global + allow/exclude windows and may add its own. An environment with no per-environment windows + is valid when global windows are defined. + items: + description: ScheduledEnvironment defines the window configuration + for a single environment. + properties: + allow: + description: |- + Allow defines the allowed promotion windows. Promotions are allowed when the current time + falls inside any of these windows (OR semantics). These are combined with any global + spec.allow windows. If no allow windows are defined (neither here nor globally), the + environment operates in exclusion-only mode. + items: + description: CronWindow defines a recurring time window using + a cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + branch: + description: |- + Branch is the name of the branch/environment you want to gate with time windows. + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + exclude: + description: |- + Exclude defines blackout periods during which promotions are blocked. Exclusions take + precedence over allow windows — if the current time falls inside any exclusion, promotions + are blocked regardless of allow windows. These are combined with any global spec.exclude + windows. If empty, no blackout periods are applied. + items: + description: CronWindow defines a recurring time window using + a cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + required: + - branch + type: object + maxItems: 1000 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + exclude: + description: |- + Exclude defines global exclusion windows applied to all listed environments in addition to + per-environment exclusions. Exclusions take precedence over allow windows. + items: + description: CronWindow defines a recurring time window using a + cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + key: + description: |- + Key is the gate name referenced in the PromotionStrategy's proposedCommitStatuses. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this scheduled commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + timezone: + default: UTC + description: |- + Timezone is the default IANA timezone name used for evaluating cron expressions across all windows. + Individual windows may override this with their own timezone field. + Defaults to UTC. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - environments + - key + - promotionStrategyRef + type: object + x-kubernetes-validations: + - message: each environment must have at least one allow or exclude window, + either per-environment or global + rule: self.environments.all(e, size(e.allow) > 0 || size(e.exclude) + > 0 || size(self.allow) > 0 || size(self.exclude) > 0) + status: + description: status defines the observed state of ScheduledCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment being + tracked. + items: + description: ScheduledEnvironmentStatus defines the observed window + state for a specific environment. + properties: + active: + description: |- + Active holds details of the currently active window driving the phase. + Nil when no specific window is active (e.g. exclusion-only mode with no active exclusion). + properties: + allow: + description: Allow is the cron expression of the allow window, + if applicable. + type: string + exclude: + description: Exclude is the cron expression of the exclusion + window, if applicable. + type: string + transition: + description: |- + Transition is when this window state is expected to change + (e.g. window closing for active, window opening for next). + format: date-time + type: string + type: object + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + next: + description: |- + Next holds details of the next expected window transition. + Used by UIs for countdown timers and by the controller for precise requeuing. + properties: + allow: + description: Allow is the cron expression of the allow window, + if applicable. + type: string + exclude: + description: Exclude is the cron expression of the exclusion + window, if applicable. + type: string + transition: + description: |- + Transition is when this window state is expected to change + (e.g. window closing for active, window opening for next). + format: date-time + type: string + type: object + phase: + description: Phase represents the current phase of the scheduled + gate. + enum: + - pending + - success + type: string + sha: + description: |- + Sha is the proposed commit SHA being tracked for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - branch + - phase + - sha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_scmproviders.yaml b/config/crd/bases/promoter.argoproj.io_scmproviders.yaml new file mode 100644 index 00000000000..a731ad0e3bb --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_scmproviders.yaml @@ -0,0 +1,258 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: scmproviders.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ScmProvider + listKind: ScmProviderList + plural: scmproviders + singular: scmprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScmProvider is the Schema for the scmproviders API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#scmprovider + 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: ScmProviderSpec defines the desired state of ScmProvider + properties: + azureDevOps: + description: AzureDevOps required configuration for Azure DevOps as + the SCM provider + properties: + domain: + description: Domain is the Azure DevOps domain, such as "dev.azure.com". + If using the default Azure DevOps domain, leave this field empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to dev.azure.com, leave + the field blank + rule: self != "dev.azure.com" + organization: + description: Organization is the Azure DevOps organization name. + maxLength: 50 + minLength: 1 + pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$ + type: string + required: + - organization + type: object + bitbucketCloud: + description: BitbucketCloud required configuration for Bitbucket Cloud + as the SCM provider + type: object + fake: + description: Fake required configuration for Fake as the SCM provider + properties: + domain: + description: Domain is the domain of the fake SCM provider. This + is used for testing purposes. + maxLength: 253 + minLength: 1 + type: string + type: object + forgejo: + description: Forgejo required configuration for Forgejo as the SCM + provider + properties: + domain: + description: |- + Domain is the Forgejo domain, such as "codeberg.org" or "forgejo.mycompany.com". + There is no default domain since Forgejo is not a service like Gitlab or Github. + maxLength: 253 + minLength: 1 + type: string + required: + - domain + type: object + gitea: + description: Gitea required configuration for Gitea as the SCM provider + properties: + domain: + description: |- + Domain is the Gitea domain, such as "gitea.com" or "gitea.mycompany.com". + There is no default domain since Gitea is self-hosted. + minLength: 1 + type: string + required: + - domain + type: object + github: + description: GitHub required configuration for GitHub as the SCM provider + properties: + appID: + description: AppID is the GitHub App ID. + format: int64 + minimum: 0 + type: integer + domain: + description: |- + Domain is the GitHub domain, such as "github.mycompany.com". If using the default GitHub domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to github.com, leave + the field blank + rule: self != "github.com" + installationID: + description: |- + InstallationID is the GitHub App Installation ID. If you want to use this ScmProvider for multiple + GitHub orgs, do not specify this field. The installation ID will be inferred from the repo owner + when needed. + format: int64 + minimum: 0 + type: integer + required: + - appID + type: object + gitlab: + description: GitLab required configuration for GitLab as the SCM provider + properties: + domain: + description: |- + Domain is the GitLab domain, such as "gitlab.mycompany.com". If using the default GitLab domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to gitlab.com, leave + the field blank + rule: self != "gitlab.com" + type: object + secretRef: + description: SecretRef contains the credentials required to auth to + a specific provider + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: ScmProviderStatus defines the observed state of ScmProvider + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_timedcommitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_timedcommitstatuses.yaml new file mode 100644 index 00000000000..e7dce7db22b --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_timedcommitstatuses.yaml @@ -0,0 +1,240 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: timedcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: TimedCommitStatus + listKind: TimedCommitStatusList + plural: timedcommitstatuses + singular: timedcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: TimedCommitStatus is the Schema for the timedcommitstatuses API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#timedcommitstatus + 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: spec defines the desired state of TimedCommitStatus + properties: + environments: + items: + description: TimedCommitStatusEnvironments defines the branch/environment + and duration to wait before reporting the gate as success. + properties: + branch: + description: Branch is the name of the branch/environment you + want to gate for the configured duration. + minLength: 1 + type: string + duration: + description: |- + Duration is the time duration to wait before considering the commit status as success. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "5m", "1h30m". + type: string + required: + - branch + - duration + type: object + type: array + key: + default: timer + description: |- + Key is the gate name referenced in the PromotionStrategy's activeCommitStatuses or + proposedCommitStatuses. When omitted, the CRD default is timer. Set Key explicitly, even if you use the CRD default. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this timed commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + required: + - environments + - promotionStrategyRef + type: object + status: + description: status defines the observed state of TimedCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment being + tracked. + items: + description: TimedCommitStatusEnvironmentsStatus defines the observed + timing status for a specific environment. + properties: + atMostDurationRemaining: + description: |- + AtMostDurationRemaining is the maximum amount of time remaining until the gate is satisfied. + This is calculated at reconciliation time. When the gate is satisfied (phase=success), this will be 0. + type: string + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + commitTime: + description: CommitTime is when the commit was deployed to the + active environment. + format: date-time + type: string + phase: + description: Phase represents the current phase of the timed + gate. + enum: + - pending + - success + type: string + requiredDuration: + description: |- + RequiredDuration is the duration that must elapse before promotion is allowed. + If this is updated in the spec with a pending time. The new duration will be calculated from the original CommitTime. + Allowing you to extend the duration of an already deployed commit, if the time has not yet elapsed. + type: string + sha: + description: |- + Sha is the commit SHA being tracked for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - atMostDurationRemaining + - branch + - commitTime + - phase + - requiredDuration + - sha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/promoter.argoproj.io_webrequestcommitstatuses.yaml b/config/crd/bases/promoter.argoproj.io_webrequestcommitstatuses.yaml new file mode 100644 index 00000000000..749a9bbaf77 --- /dev/null +++ b/config/crd/bases/promoter.argoproj.io_webrequestcommitstatuses.yaml @@ -0,0 +1,856 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: webrequestcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: WebRequestCommitStatus + listKind: WebRequestCommitStatusList + plural: webrequestcommitstatuses + singular: webrequestcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.key + name: Key + type: string + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .spec.reportOn + name: ReportOn + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: WebRequestCommitStatus is the Schema for the webrequestcommitstatuses + API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#webrequestcommitstatus + 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: spec defines the desired state of WebRequestCommitStatus + properties: + descriptionTemplate: + description: |- + DescriptionTemplate is the human-readable commit status description in the SCM provider (GitHub, GitLab, etc.). + Uses Go templates; variable list and Sprig rules match HTTPRequestSpec (spec.httpRequest). Rendered with the latest + data after the most recent HTTP request and trigger evaluation (unlike spec.httpRequest URL/body/headers, which use pre-request data — see HTTPRequestSpec). + How spec.mode.context restricts template data: see ModeSpec. + + Additional template variables (not in HTTPRequestSpec): + - {{ index .TriggerVariables "key" }}: result of trigger.when.variables.expression this reconcile (nil if not configured) + - {{ index .SuccessVariables "key" }}: result of success.when.variables.expression this reconcile (nil if not configured) + + Examples: "External approval for {{ .Branch }}", "{{ .Phase }} - waiting for external approval". + + If not specified, defaults to empty string. + type: string + httpRequest: + description: HTTPRequest configures the outbound HTTP call. See HTTPRequestSpec. + properties: + authentication: + description: |- + Authentication specifies authentication configuration for the HTTP request. + + Supports multiple authentication methods: + - Basic Auth: HTTP Basic Authentication with username/password + - Bearer Token: Bearer token authentication (e.g., API keys, JWTs) + - OAuth2: OAuth2 client credentials flow for obtaining access tokens + - TLS: Mutual TLS (mTLS) with client certificates + - SCM: Reuses credentials from the ScmProvider referenced by the PromotionStrategy (no extra secret needed) + + For Basic, Bearer, OAuth2, and TLS, credentials must be stored in Kubernetes secrets and referenced via secretRef fields. + For SCM, credentials are obtained automatically from the SCM provider; just set scm: {}. + + Examples: + # Basic Auth + authentication: + basic: + secretRef: + name: my-creds + + # Bearer Token + authentication: + bearer: + secretRef: + name: api-token + + # OAuth2 Client Credentials + authentication: + oauth2: + tokenURL: "https://auth.example.com/oauth/token" + secretRef: + name: oauth-creds + + # TLS Client Certificate + authentication: + tls: + secretRef: + name: my-tls-cert + + # SCM Provider Credentials + authentication: + scm: {} + properties: + basic: + description: |- + Basic specifies HTTP Basic Authentication. + Credentials can be provided inline (with secret references) or via secretRef. + properties: + secretRef: + description: |- + SecretRef references a secret containing username and password. + The secret must contain keys "username" and "password". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + bearer: + description: |- + Bearer specifies Bearer token authentication. + Token can be provided inline (with secret reference) or via secretRef. + properties: + secretRef: + description: |- + SecretRef references a secret containing the bearer token. + The secret must contain key "token". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + oauth2: + description: |- + OAuth2 specifies OAuth2 client credentials authentication. + The controller will automatically obtain access tokens from the specified tokenURL. + properties: + scopes: + description: |- + Scopes to request from the OAuth2 provider. + Optional - some providers don't require scopes for client credentials. + Example: ["read:api", "write:api"] + items: + type: string + type: array + secretRef: + description: |- + SecretRef references a secret containing clientID and clientSecret. + The secret must contain keys "clientID" and "clientSecret". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + tokenURL: + description: |- + TokenURL is the OAuth2 token endpoint where access tokens are obtained. + Example: "https://auth.example.com/oauth/token" + type: string + required: + - secretRef + - tokenURL + type: object + scm: + description: |- + Scm specifies authentication using credentials from the SCM provider. + This uses the credentials configured in the ScmProvider referenced by the PromotionStrategy, + applying the appropriate authentication method based on the SCM provider type + (GitHub App, GitLab token, Azure DevOps PAT, etc.). + To use this auth type, just set it to an empty object, i.e. scm: {}. + type: object + tls: + description: |- + TLS specifies TLS client certificate authentication (mutual TLS). + Requires a secret containing the client certificate and private key. + properties: + secretRef: + description: |- + SecretRef references a secret containing TLS certificate and key. + The secret should be of type kubernetes.io/tls or contain keys "tls.crt" and "tls.key", and optionally "ca.crt". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [basic bearer oauth2 tls + scm] may be set + rule: '[has(self.basic),has(self.bearer),has(self.oauth2),has(self.tls),has(self.scm)].filter(x,x==true).size() + <= 1' + bodyTemplate: + description: |- + BodyTemplate is the request body to send. + Supports Go templates (see HTTPRequestSpec for available variables). + type: string + headerTemplates: + additionalProperties: + type: string + description: |- + HeaderTemplates are additional HTTP headers to include in the request. + The map key is the header name and the value is the header value (supports Go templates). + See HTTPRequestSpec for available template variables. + type: object + method: + description: |- + Method is the static HTTP method to use. Mutually exclusive with MethodTemplate. + + Deprecated: Use MethodTemplate instead. A literal value such as `methodTemplate: GET` behaves + identically to `method: GET` and avoids needing two separate fields. Existing resources that + set Method continue to work, but new resources should set MethodTemplate. Method may be + removed in a future release. + enum: + - GET + - POST + - PUT + - PATCH + - DELETE + type: string + methodTemplate: + description: |- + MethodTemplate is the HTTP method, rendered as a Go template with the same variables and + Sprig functions as URLTemplate/BodyTemplate/HeaderTemplates. The rendered string is trimmed + of surrounding whitespace and uppercased; the final value must be one of GET/POST/PUT/PATCH/DELETE + or the reconcile returns an error. A literal value such as `methodTemplate: GET` works + identically to a static method; use templating when the method must vary by reconcile + state (e.g. issuing a search GET on one reconcile and a close POST on the next). + Mutually exclusive with Method (deprecated). + type: string + timeout: + default: 30s + description: Timeout is the maximum time to wait for the HTTP + request to complete. + type: string + urlTemplate: + description: |- + URLTemplate is the HTTP endpoint to request. + Supports Go templates (see HTTPRequestSpec for available variables). + type: string + required: + - urlTemplate + type: object + x-kubernetes-validations: + - message: exactly one of method or methodTemplate must be set + rule: (has(self.method) && self.method.size() > 0) != (has(self.methodTemplate) + && self.methodTemplate.size() > 0) + key: + description: |- + Key is the unique identifier for this validation rule. + It is used as the commit status key and in status messages. + This key is matched against PromotionStrategy's proposedCommitStatuses or activeCommitStatuses + to determine which environments this validation applies to. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + mode: + description: Mode selects polling vs trigger and request scope (context). + See ModeSpec. + properties: + context: + default: environments + description: Context is "environments" (default) or "promotionstrategy". + See the ModeSpec type documentation for behavior, template limits, + and success expression rules. + enum: + - environments + - promotionstrategy + type: string + polling: + description: |- + Polling enables interval-based polling mode. + The controller will poll the HTTP endpoint at the specified interval. + properties: + interval: + default: 1m + description: |- + Interval controls how often to retry the HTTP request while in pending state. + When reportOn is "proposed": stops polling after success for a given SHA. + When reportOn is "active": always polls at this interval. + type: string + type: object + trigger: + description: |- + Trigger enables expression-based triggering mode. + The controller will evaluate the expression to determine when to make HTTP requests. + properties: + requeueDuration: + default: 1m + description: RequeueDuration specifies how long to wait before + requeuing to re-evaluate the trigger expression. + type: string + response: + description: Response optionally configures an expression + that extracts data from the HTTP response into ResponseOutput. + properties: + output: + description: |- + Output is evaluated after the HTTP request completes (any status). Response variables are the same as for spec.success.when.expression — see WhenWithOutputSpec.Expression. + The result is stored in status (environments[].responseOutput or promotionStrategyContext.responseOutput) and exposed on the next reconcile as ResponseOutput in trigger expressions and templates. + Must return a map/object. + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + required: + - output + type: object + when: + description: When configures the boolean guard and optional + output expression that control whether the HTTP request + is made. + properties: + expression: + description: |- + Expression is a boolean expr expression that decides whether the HTTP request should be made. + It is evaluated BEFORE each potential HTTP request. When it returns true the request is made; + when false the controller keeps the previous phase and skips the request. + + Available variables: + - Branch (string): the environment branch currently being processed (empty for the shared HTTP request in promotionstrategy context) + - Phase (string): previous reconcile's phase — per-environment in environments context; aggregate of all branches in promotionstrategy context (success only if all succeeded, failure if any failed, pending otherwise) + - PromotionStrategy (PromotionStrategy): the full PromotionStrategy spec and status + - WebRequestCommitStatus (WebRequestCommitStatus): the full WebRequestCommitStatus spec and status (snapshot from the previous reconcile) + - TriggerOutput (map[string]any): custom data from the previous when.output.expression evaluation + - ResponseOutput (map[string]any): response data from the previous HTTP request (if any) + - SuccessOutput (map[string]any): custom data from the previous success.when.output.expression evaluation + - Variables (map[string]any): when spec.variables is set, the map returned by variables.expression this reconcile; omitted otherwise + + Note: PromotionStrategy.Status.Environments is an ordered array representing the promotion sequence. + Use Branch + filter/find to look up environment-specific data: + find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha + + Examples: + # Always trigger (equivalent to polling mode) + - "true" + + # Only trigger when SHA changes from what we last tracked + - "find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha != (TriggerOutput['lastCheckedSha'] ?? '')" + + # Only trigger when a particular commit status is success (e.g. argocd-health) + - "let env = find(PromotionStrategy.Status.Environments, {.Branch == Branch}); any(env.Proposed.CommitStatuses, {.Key == 'argocd-health' && .Phase == 'success'})" + + # Only retry if the previous response indicated we should + - "ResponseOutput == nil || ResponseOutput.status == 'retry'" + type: string + output: + description: |- + Output optionally holds an expression that produces a map of data to persist across reconcile cycles. + The expression runs on every reconcile (whether or not the HTTP request is made). Its result is stored in + status (per-environment under environments[].triggerOutput, or under promotionStrategyContext.triggerOutput when context is promotionstrategy) + and is available in the next reconcile as TriggerOutput in when.expression, when.output.expression, and in templates. + Use it to track state such as attempt counts, last-seen SHAs, or timestamps. + + Delivery semantics caveat: persisted output is read from the controller's informer cache at the start of the next + reconcile. Under cache-propagation lag, controller restarts, or status-write retries, the next reconcile may not + see the most recently persisted output and may re-fire the HTTP request. Treat this as AT-LEAST-ONCE delivery — + counters built on TriggerOutput are eventually-consistent (a stale read can cause a duplicate increment), so use + them for backoff hints, not for hard "fail after N attempts" gates. + + Variables are the same as for Expression (see above). The expression must return a map/object; every key is stored in TriggerOutput. + + Examples: + # Track SHA to detect changes (idempotent: replays produce the same trackedSha for the same input) + - "{ trackedSha: find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha }" + + # Increment attempt counter (eventually-consistent; may briefly under-count under cache lag) + - "{ attemptCount: (TriggerOutput[\"attemptCount\"] ?? 0) + 1 }" + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + variables: + description: |- + Variables optionally holds an expression that runs before Expression and Output.Expression. + It receives the same variables as Expression (see Expression documentation below) and must return a map/object. + The result is injected as top-level binding Variables (map) for Expression and Output.Expression only — use Variables. in those expressions. + The Variables binding is not set when spec.variables is omitted. It is not available to response.output.expression. + The result is also available in Go templates for DescriptionTemplate and UrlTemplate: + - trigger.when.variables result → {{ index .TriggerVariables "key" }} + - success.when.variables result → {{ index .SuccessVariables "key" }} + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + required: + - expression + type: object + required: + - when + type: object + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [polling trigger] must be + set + rule: '[has(self.polling),has(self.trigger)].filter(x,x==true).size() + == 1' + promotionStrategyRef: + description: |- + PromotionStrategyRef references the PromotionStrategy this applies to. + The controller will check commits from ALL environments in the referenced PromotionStrategy + where this WebRequestCommitStatus.Spec.Key matches an entry in either: + - PromotionStrategy.Spec.ProposedCommitStatuses (applies to all environments), OR + - PromotionStrategy.Spec.ActiveCommitStatuses (applies to all environments), OR + - Environment.ProposedCommitStatuses (applies to specific environment), OR + - Environment.ActiveCommitStatuses (applies to specific environment) + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + reportOn: + default: proposed + description: |- + ReportOn specifies which commit SHA to report the CommitStatus on. + - "proposed": Reports on the proposed hydrated commit SHA (default) + - "active": Reports on the active hydrated commit SHA + + When "proposed": Polls until success, then stops polling for that SHA. + Use "proposed" for checks that need to run just once before a change is promoted, like an approval step. + + When "active": Polls forever, even after success (active state can change). + Use "active" for checks that monitor the change after it's released, for example a metrics monitoring service. + enum: + - proposed + - active + type: string + success: + description: Success defines when the commit status phase is success. + Evaluated every reconcile. See SuccessSpec. + properties: + when: + description: When is evaluated every reconcile. See WhenWithOutputSpec.Expression. + properties: + expression: + description: |- + Expression is a boolean expr expression that decides whether the HTTP request should be made. + It is evaluated BEFORE each potential HTTP request. When it returns true the request is made; + when false the controller keeps the previous phase and skips the request. + + Available variables: + - Branch (string): the environment branch currently being processed (empty for the shared HTTP request in promotionstrategy context) + - Phase (string): previous reconcile's phase — per-environment in environments context; aggregate of all branches in promotionstrategy context (success only if all succeeded, failure if any failed, pending otherwise) + - PromotionStrategy (PromotionStrategy): the full PromotionStrategy spec and status + - WebRequestCommitStatus (WebRequestCommitStatus): the full WebRequestCommitStatus spec and status (snapshot from the previous reconcile) + - TriggerOutput (map[string]any): custom data from the previous when.output.expression evaluation + - ResponseOutput (map[string]any): response data from the previous HTTP request (if any) + - SuccessOutput (map[string]any): custom data from the previous success.when.output.expression evaluation + - Variables (map[string]any): when spec.variables is set, the map returned by variables.expression this reconcile; omitted otherwise + + Note: PromotionStrategy.Status.Environments is an ordered array representing the promotion sequence. + Use Branch + filter/find to look up environment-specific data: + find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha + + Examples: + # Always trigger (equivalent to polling mode) + - "true" + + # Only trigger when SHA changes from what we last tracked + - "find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha != (TriggerOutput['lastCheckedSha'] ?? '')" + + # Only trigger when a particular commit status is success (e.g. argocd-health) + - "let env = find(PromotionStrategy.Status.Environments, {.Branch == Branch}); any(env.Proposed.CommitStatuses, {.Key == 'argocd-health' && .Phase == 'success'})" + + # Only retry if the previous response indicated we should + - "ResponseOutput == nil || ResponseOutput.status == 'retry'" + type: string + output: + description: |- + Output optionally holds an expression that produces a map of data to persist across reconcile cycles. + The expression runs on every reconcile (whether or not the HTTP request is made). Its result is stored in + status (per-environment under environments[].triggerOutput, or under promotionStrategyContext.triggerOutput when context is promotionstrategy) + and is available in the next reconcile as TriggerOutput in when.expression, when.output.expression, and in templates. + Use it to track state such as attempt counts, last-seen SHAs, or timestamps. + + Delivery semantics caveat: persisted output is read from the controller's informer cache at the start of the next + reconcile. Under cache-propagation lag, controller restarts, or status-write retries, the next reconcile may not + see the most recently persisted output and may re-fire the HTTP request. Treat this as AT-LEAST-ONCE delivery — + counters built on TriggerOutput are eventually-consistent (a stale read can cause a duplicate increment), so use + them for backoff hints, not for hard "fail after N attempts" gates. + + Variables are the same as for Expression (see above). The expression must return a map/object; every key is stored in TriggerOutput. + + Examples: + # Track SHA to detect changes (idempotent: replays produce the same trackedSha for the same input) + - "{ trackedSha: find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha }" + + # Increment attempt counter (eventually-consistent; may briefly under-count under cache lag) + - "{ attemptCount: (TriggerOutput[\"attemptCount\"] ?? 0) + 1 }" + properties: + expression: + description: Expression is an expr expression that must + return a map/object. + type: string + required: + - expression + type: object + variables: + description: |- + Variables optionally holds an expression that runs before Expression and Output.Expression. + It receives the same variables as Expression (see Expression documentation below) and must return a map/object. + The result is injected as top-level binding Variables (map) for Expression and Output.Expression only — use Variables. in those expressions. + The Variables binding is not set when spec.variables is omitted. It is not available to response.output.expression. + The result is also available in Go templates for DescriptionTemplate and UrlTemplate: + - trigger.when.variables result → {{ index .TriggerVariables "key" }} + - success.when.variables result → {{ index .SuccessVariables "key" }} + properties: + expression: + description: Expression is an expr expression that must + return a map/object. + type: string + required: + - expression + type: object + required: + - expression + type: object + required: + - when + type: object + urlTemplate: + description: |- + UrlTemplate is the commit status target URL in the SCM provider. Same Go templates, variables (including .TriggerVariables and .SuccessVariables), timing, and context rules as DescriptionTemplate. + Typical uses: approval UI, dashboard, API, or runbook links. + To include the reported SHA, walk PromotionStrategy.Status.Environments by Branch: + "https://approvals.example.com/{{ range .PromotionStrategy.Status.Environments }}{{ if eq .Branch $.Branch }}{{ .Proposed.Hydrated.Sha }}{{ end }}{{ end }}" + For branch-only links: "https://dashboard.example.com/{{ .Branch }}/status". + + If not specified, defaults to empty string (no URL shown). + type: string + required: + - httpRequest + - key + - mode + - promotionStrategyRef + - success + type: object + status: + description: status defines the observed state of WebRequestCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: |- + Environments holds the status of each environment when context is "environments". + When context is "promotionstrategy", this slice is empty and PromotionStrategyContext is used instead. + items: + description: |- + WebRequestCommitStatusEnvironmentStatus defines the observed status for a specific environment. + + TriggerOutput, ResponseOutput, and SuccessOutput hold JSON maps written by their respective output expressions. + They are surfaced on the next reconcile as TriggerOutput, ResponseOutput, and SuccessOutput in expr and templates (see WhenWithOutputSpec and HTTPRequestSpec). + properties: + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + lastRequestTime: + description: LastRequestTime is when the last HTTP request was + made. + format: date-time + type: string + lastResponseStatusCode: + description: LastResponseStatusCode is the HTTP status code + from the last request. + type: integer + lastSuccessfulSha: + description: |- + LastSuccessfulSha is the last commit SHA that achieved success status for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + phase: + description: |- + Phase represents the current phase of the validation. + This controller sets only "pending" or "success"; it never sets "failure" (failure is allowed by the enum for API consistency). + enum: + - pending + - success + - failure + type: string + reportedSha: + description: |- + ReportedSha is the commit SHA being reported on for this environment. + This is determined by the reportOn field (proposed or active). + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + responseOutput: + description: ResponseOutput is the map from spec.mode.trigger.response.output.expression + when spec.mode.trigger.response is set; otherwise nil. + type: object + x-kubernetes-preserve-unknown-fields: true + successOutput: + description: |- + SuccessOutput is the map from spec.success.when.output.expression (arbitrary JSON keys). + Evaluated every reconcile (whether or not an HTTP request was made). The result is stored here and + exposed on the next reconcile as SuccessOutput in trigger/success expressions and templates. + type: object + x-kubernetes-preserve-unknown-fields: true + triggerOutput: + description: TriggerOutput is the map from spec.mode.trigger.when.output.expression + (arbitrary JSON keys). + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - branch + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + promotionStrategyContext: + description: |- + PromotionStrategyContext holds the result of the one HTTP run when context is "promotionstrategy". + At most one request is made per WebRequestCommitStatus; phase(s) are reported on each environment's CommitStatus. + properties: + lastRequestTime: + description: LastRequestTime is when the last HTTP request was + made. + format: date-time + type: string + lastResponseStatusCode: + description: LastResponseStatusCode is the HTTP status code from + the last request. + type: integer + lastSuccessfulShas: + description: |- + LastSuccessfulShas tracks the last SHA that achieved success for each branch. + Used with reportOn "proposed" + polling to skip HTTP requests when all environments + have already succeeded for their current SHAs. + items: + description: WebRequestCommitStatusLastSuccessfulShaItem records + the last successful SHA for one branch in promotionstrategy + context status. + properties: + branch: + description: Branch is the environment branch name (merge + key for lastSuccessfulShas list). + minLength: 1 + type: string + lastSuccessfulSha: + description: LastSuccessfulSha is the SHA that last achieved + success for this branch. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + required: + - branch + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + phasePerBranch: + description: |- + PhasePerBranch holds the resolved phase for each applicable branch. + Every applicable branch is always present after reconciliation. + items: + description: WebRequestCommitStatusPhasePerBranchItem is one + branch's resolved phase in promotionstrategy context status. + properties: + branch: + description: Branch is the environment branch name (merge + key for phasePerBranch list). + minLength: 1 + type: string + phase: + description: Phase is "pending", "success", or "failure". + enum: + - pending + - success + - failure + type: string + required: + - branch + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + responseOutput: + description: 'ResponseOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.ResponseOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + successOutput: + description: 'SuccessOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.SuccessOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + triggerOutput: + description: 'TriggerOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.TriggerOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/manifests/bases/gitops-operator.clusterserviceversion.yaml b/config/manifests/bases/gitops-operator.clusterserviceversion.yaml index c91e1f76b4d..f4387c4f0fc 100644 --- a/config/manifests/bases/gitops-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/gitops-operator.clusterserviceversion.yaml @@ -137,6 +137,85 @@ spec: kind: ImageUpdater name: imageupdaters.argocd-image-updater.argoproj.io version: v1alpha1 + - description: ArgoCDCommitStatus is used as a way to aggregate all the Argo CD + Applications that are being used in a promotion strategy. + displayName: ArgoCDCommitStatus + kind: ArgoCDCommitStatus + name: argocdcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: ChangeTransferPolicy represents a pair hydrated environment branch + pair of the proposed environment branch and the live environment branch. + displayName: ChangeTransferPolicy + kind: ChangeTransferPolicy + name: changetransferpolicies.promoter.argoproj.io + version: v1alpha1 + - description: ClusterScmProvider is a cluster-scoped SCM instance (such as GitHub). + displayName: ClusterSCMProvider + kind: ClusterScmProvider + name: clusterscmproviders.promoter.argoproj.io + version: v1alpha1 + - description: CommitStatus is a thin wrapper for the SCM's commit status API. + displayName: CommitStatus + kind: CommitStatus + name: commitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: ControllerConfiguration is used to configure the behavior of the + promoter. + displayName: ControllerConfiguration + kind: ControllerConfiguration + name: controllerconfigurations.promoter.argoproj.io + version: v1alpha1 + - description: GitCommitStatus evaluates commit data with a custom expression + for promotion gating. + displayName: GitCommitStatus + kind: GitCommitStatus + name: gitcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: GitRepository represents a single git repository. + displayName: GitRepository + kind: GitRepository + name: gitrepositories.promoter.argoproj.io + version: v1alpha1 + - description: PromotionStrategy is the user's interface to controlling how changes + are promoted through their environments. + displayName: PromotionStrategy + kind: PromotionStrategy + name: promotionstrategies.promoter.argoproj.io + version: v1alpha1 + - description: PullRequest represents a thin wrapper around the SCM's pull request + API. + displayName: PullRequest + kind: PullRequest + name: pullrequests.promoter.argoproj.io + version: v1alpha1 + - description: RevertCommit represents a revert commit created to roll back a + promotion. + displayName: RevertCommit + kind: RevertCommit + name: revertcommits.promoter.argoproj.io + version: v1alpha1 + - description: ScheduledCommitStatus provides calendar-based gating for environment + promotions. + displayName: ScheduledCommitStatus + kind: ScheduledCommitStatus + name: scheduledcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: ScmProvider represents a SCM instance (such as GitHub). + displayName: ScmProvider + kind: ScmProvider + name: scmproviders.promoter.argoproj.io + version: v1alpha1 + - description: TimedCommitStatus provides time-based gating for environment promotions. + displayName: TimedCommitStatus + kind: TimedCommitStatus + name: timedcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: WebRequestCommitStatus gates promotions on external HTTP/HTTPS + API validation. + displayName: WebRequestCommitStatus + kind: WebRequestCommitStatus + name: webrequestcommitstatuses.promoter.argoproj.io + version: v1alpha1 - description: GitopsService is the Schema for the gitopsservices API displayName: Gitops Service kind: GitopsService diff --git a/go.mod b/go.mod index 73e186f9b1c..13b959e01ad 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/redhat-developer/gitops-operator -go 1.26.3 +go 1.26.5 require ( github.com/argoproj-labs/argo-rollouts-manager v0.0.9-0.20260505092152-3e07addcb2cb github.com/argoproj-labs/argocd-image-updater v1.3.0 - github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260731050707-513e881fcd8e + github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260824193734-c354222740c1 github.com/argoproj/argo-cd/gitops-engine v0.7.1-0.20250908182407-97ad5b59a627 github.com/argoproj/argo-cd/v3 v3.5.1 github.com/go-logr/logr v1.4.4 @@ -21,20 +21,20 @@ require ( github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.28.0 - golang.org/x/mod v0.38.0 + golang.org/x/mod v0.40.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools v2.2.0+incompatible - k8s.io/api v0.36.1 - k8s.io/apiextensions-apiserver v0.36.1 - k8s.io/apimachinery v0.36.1 - k8s.io/client-go v0.36.1 - k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 + k8s.io/api v0.36.4 + k8s.io/apiextensions-apiserver v0.36.2 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.4 + k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/yaml v1.6.0 ) require ( - cel.dev/expr v0.25.1 // indirect + cel.dev/expr v0.25.2 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cyphar.com/go-pathrs v0.2.2 // indirect dario.cat/mergo v1.0.2 // indirect @@ -44,10 +44,11 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/Masterminds/semver/v3 v3.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect + github.com/argoproj-labs/gitops-promoter v0.35.0 // indirect github.com/argoproj/pkg/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -74,7 +75,7 @@ require ( github.com/fatih/camelcase v1.0.0 // indirect github.com/felixge/httpsnoop v1.1.0 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.2 // indirect github.com/go-errors/errors v1.5.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.9.0 // indirect @@ -82,20 +83,20 @@ require ( github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.23.1 // indirect - github.com/go-openapi/jsonreference v0.21.6 // indirect - github.com/go-openapi/swag v0.26.0 // indirect - github.com/go-openapi/swag/cmdutils v0.26.0 // indirect - github.com/go-openapi/swag/conv v0.26.1 // indirect - github.com/go-openapi/swag/fileutils v0.26.0 // indirect - github.com/go-openapi/swag/jsonname v0.26.1 // indirect - github.com/go-openapi/swag/jsonutils v0.26.1 // indirect - github.com/go-openapi/swag/loading v0.26.1 // indirect - github.com/go-openapi/swag/mangling v0.26.1 // indirect - github.com/go-openapi/swag/netutils v0.26.0 // indirect - github.com/go-openapi/swag/stringutils v0.26.1 // indirect - github.com/go-openapi/swag/typeutils v0.26.1 // indirect - github.com/go-openapi/swag/yamlutils v0.26.1 // indirect + github.com/go-openapi/jsonpointer v1.0.0 // indirect + github.com/go-openapi/jsonreference v1.0.0 // indirect + github.com/go-openapi/swag v0.28.0 // indirect + github.com/go-openapi/swag/cmdutils v0.28.0 // indirect + github.com/go-openapi/swag/conv v0.28.0 // indirect + github.com/go-openapi/swag/fileutils v0.28.0 // indirect + github.com/go-openapi/swag/jsonutils v0.28.0 // indirect + github.com/go-openapi/swag/loading v0.28.0 // indirect + github.com/go-openapi/swag/mangling v0.28.0 // indirect + github.com/go-openapi/swag/netutils v0.28.0 // indirect + github.com/go-openapi/swag/pools v0.28.0 // indirect + github.com/go-openapi/swag/stringutils v0.28.0 // indirect + github.com/go-openapi/swag/typeutils v0.28.0 // indirect + github.com/go-openapi/swag/yamlutils v0.28.0 // indirect github.com/go-redis/cache/v9 v9.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect @@ -105,7 +106,7 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/cel-go v0.29.0 // indirect + github.com/google/cel-go v0.30.0 // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-github/v69 v69.2.0 // indirect github.com/google/go-github/v88 v88.0.0 // indirect @@ -123,7 +124,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.19.1 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/klauspost/cpuid/v2 v2.4.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -165,56 +166,56 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + go.opentelemetry.io/proto/otlp v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.54.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/crypto v0.55.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect golang.org/x/net v0.57.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.22.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.40.0 // indirect + golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.47.0 // indirect + golang.org/x/tools v0.49.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/grpc v1.82.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect + google.golang.org/grpc v1.83.0 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiserver v0.36.1 // indirect - k8s.io/cli-runtime v0.36.1 // indirect - k8s.io/component-base v0.36.1 // indirect - k8s.io/component-helpers v0.36.1 // indirect + k8s.io/apiserver v0.36.4 // indirect + k8s.io/cli-runtime v0.36.4 // indirect + k8s.io/component-base v0.36.4 // indirect + k8s.io/component-helpers v0.36.4 // indirect k8s.io/controller-manager v0.36.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect k8s.io/kube-aggregator v0.36.1 // indirect - k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288 // indirect + k8s.io/kube-openapi v0.0.0-20260706235625-cdb1db5517a0 // indirect k8s.io/kubectl v0.36.1 // indirect k8s.io/kubernetes v1.36.1 // indirect - k8s.io/streaming v0.36.1 // indirect + k8s.io/streaming v0.36.4 // indirect oras.land/oras-go/v2 v2.6.2 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0 // indirect sigs.k8s.io/gateway-api v1.5.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.21.1 // indirect sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect ) replace ( @@ -230,37 +231,39 @@ replace ( // Avoid CVE-2022-3064 gopkg.in/yaml.v2 => gopkg.in/yaml.v2 v2.4.0 - k8s.io/api => k8s.io/api v0.36.1 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.36.1 - k8s.io/apimachinery => k8s.io/apimachinery v0.36.1 - k8s.io/apiserver => k8s.io/apiserver v0.36.1 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.36.1 - k8s.io/client-go => k8s.io/client-go v0.36.1 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.36.1 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.36.1 - k8s.io/code-generator => k8s.io/code-generator v0.36.1 - k8s.io/component-base => k8s.io/component-base v0.36.1 - k8s.io/component-helpers => k8s.io/component-helpers v0.36.1 - k8s.io/controller-manager => k8s.io/controller-manager v0.36.1 - k8s.io/cri-api => k8s.io/cri-api v0.36.1 - k8s.io/cri-client => k8s.io/cri-client v0.36.1 - k8s.io/cri-streaming => k8s.io/cri-streaming v0.36.1 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.36.1 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.36.1 - k8s.io/endpointslice => k8s.io/endpointslice v0.36.1 - k8s.io/externaljwt => k8s.io/externaljwt v0.36.1 - k8s.io/kms => k8s.io/kms v0.36.1 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.36.1 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.36.1 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.36.1 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.36.1 - k8s.io/kubectl => k8s.io/kubectl v0.36.1 - k8s.io/kubelet => k8s.io/kubelet v0.36.1 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.36.1 - k8s.io/metrics => k8s.io/metrics v0.36.1 - k8s.io/mount-utils => k8s.io/mount-utils v0.36.1 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.36.1 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.36.1 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.36.1 - k8s.io/sample-controller => k8s.io/sample-controller v0.36.1 + // Avoid CVE-2022-28948 + gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 + + k8s.io/api => k8s.io/api v0.36.4 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.36.4 + k8s.io/apimachinery => k8s.io/apimachinery v0.36.4 + k8s.io/apiserver => k8s.io/apiserver v0.36.4 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.36.4 + k8s.io/client-go => k8s.io/client-go v0.36.4 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.36.4 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.36.4 + k8s.io/code-generator => k8s.io/code-generator v0.36.4 + k8s.io/component-base => k8s.io/component-base v0.36.4 + k8s.io/component-helpers => k8s.io/component-helpers v0.36.4 + k8s.io/controller-manager => k8s.io/controller-manager v0.36.4 + k8s.io/cri-api => k8s.io/cri-api v0.36.4 + k8s.io/cri-client => k8s.io/cri-client v0.36.4 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.36.4 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.36.4 + k8s.io/endpointslice => k8s.io/endpointslice v0.36.4 + k8s.io/externaljwt => k8s.io/externaljwt v0.36.4 + k8s.io/kms => k8s.io/kms v0.36.4 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.36.4 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.36.4 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.36.4 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.36.4 + k8s.io/kubectl => k8s.io/kubectl v0.36.4 + k8s.io/kubelet => k8s.io/kubelet v0.36.4 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.36.4 + k8s.io/metrics => k8s.io/metrics v0.36.4 + k8s.io/mount-utils => k8s.io/mount-utils v0.36.4 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.36.4 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.36.4 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.36.4 + k8s.io/sample-controller => k8s.io/sample-controller v0.36.4 ) diff --git a/go.sum b/go.sum index cb306936715..780545b21dd 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= -cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= +cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= @@ -25,8 +25,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2/go.mod h1:HKpQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= +github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -43,8 +43,10 @@ github.com/argoproj-labs/argo-rollouts-manager v0.0.9-0.20260505092152-3e07addcb github.com/argoproj-labs/argo-rollouts-manager v0.0.9-0.20260505092152-3e07addcb2cb/go.mod h1:Ouqjtkj48SPJhW6r00CYqJ4uM7QDy3D4tinKIK9Y69Q= github.com/argoproj-labs/argocd-image-updater v1.3.0 h1:MFqUKURoh14wV1ansPGFnzLIvUGhzWOMU8L2x96041U= github.com/argoproj-labs/argocd-image-updater v1.3.0/go.mod h1:7h1LqHoKavqo8rofiSPnzMK55n77WrnwCLxtgOb3AtI= -github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260731050707-513e881fcd8e h1:TocoyPvGB+Hf0pWLqIUySr+LsXpK/IylmatMVDLEsBo= -github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260731050707-513e881fcd8e/go.mod h1:WlaJ1K/BaF0qhltQEoYv8PYwns9/F6/v+dJWMyOi+U0= +github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260824193734-c354222740c1 h1:8oereBYBbvk8CAibLm387pR2P6An0UqTPVsmy5MT5Hg= +github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260824193734-c354222740c1/go.mod h1:bm/IUX9v7NrneEklwsn9R03ebpGKasOvxbziY4HEqnc= +github.com/argoproj-labs/gitops-promoter v0.35.0 h1:uma781gA0XW9Or0RuMnQFwe6ikZUAz/tmStRDSR44r4= +github.com/argoproj-labs/gitops-promoter v0.35.0/go.mod h1:t6ndi4HS6lixaYyFpNALRQd8R34jbCXsZMxWvOT4dzk= github.com/argoproj/argo-cd/gitops-engine v0.0.0-20260812112440-109ca7ca7113 h1:Datv/1guNla320d6ZaHTSaxB3bUVzO83NyeY6LaUjvM= github.com/argoproj/argo-cd/gitops-engine v0.0.0-20260812112440-109ca7ca7113/go.mod h1:RsOM4gdM/lsvAfIuzAhYrnHDTLA1AGooZRzVyxbVT3A= github.com/argoproj/argo-cd/v3 v3.5.1 h1:jtwPLEFX9mNj3jSq88ugFcScGnOZVs2DWaXFuZxrRT8= @@ -128,16 +130,16 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2 github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc= github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE= 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.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= @@ -167,40 +169,40 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= -github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= -github.com/go-openapi/jsonreference v0.21.6 h1:NZ5nGfnaM1n4I43Xjm1e5/M2GjOwQwndQz22uhxwD+Y= -github.com/go-openapi/jsonreference v0.21.6/go.mod h1:xzbgtQ3ZbWxvET3AxdzCJlJt6vkovbf+IfSPJjD0tUY= -github.com/go-openapi/swag v0.26.0 h1:GVDXCmfvhfu1BxiHo8/FA+BbKmhecHnG3varjON5/RI= -github.com/go-openapi/swag v0.26.0/go.mod h1:82g3193sZJRbocs7bNCqGfIgq8pkuwVwCfhKIRlEQF0= -github.com/go-openapi/swag/cmdutils v0.26.0 h1:iowihOcvq7y4egO8cOq0dmfohz6wfeQ63U1EnuhO2TU= -github.com/go-openapi/swag/cmdutils v0.26.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= -github.com/go-openapi/swag/conv v0.26.1 h1:slr5FVkg9Wc3Y5zcwenD8Sd/PQ94b2I/QJI7N7KTBpg= -github.com/go-openapi/swag/conv v0.26.1/go.mod h1:mvQXgPptZk9GTrFgGwWvT4q+dN+zQej9JfmGwnipz1A= -github.com/go-openapi/swag/fileutils v0.26.0 h1:WJoPRvsA7QRiiWluowkLJa9jaYR7FCuxmDvnCgaRRxU= -github.com/go-openapi/swag/fileutils v0.26.0/go.mod h1:0WDJ7lp67eNjPMO50wAWYlKvhOb6CQ37rzR7wrgI8Tc= -github.com/go-openapi/swag/jsonname v0.26.1 h1:VReupaV6WxlAsCn0e4DUfgV6bPmINnPpyJDLqSfNPcE= -github.com/go-openapi/swag/jsonname v0.26.1/go.mod h1:OvdW6BoWoj33pTfi7x9vFrgmT+fk7aw0BRwvCE0YOuc= -github.com/go-openapi/swag/jsonutils v0.26.1 h1:2hdBfFkHg+7Wrz2VsCbeyR6hzkRDs7AztnMR2u84yOY= -github.com/go-openapi/swag/jsonutils v0.26.1/go.mod h1:U+RMJH3wa+6BRiphuRtIyI8fW9HPFqFQ4sHk2oRx0UQ= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.1 h1:1CD7NiLLb/TXl3tOnFYU4b+mNfb5rtgHkaA+q7RMYYQ= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.26.1/go.mod h1:ZWafc8nMdYzTE3uYY6W86f0n46+IF0g4uUyRhJw/kXc= -github.com/go-openapi/swag/loading v0.26.1 h1:E9K4wqXeROlhjFQ13K9zMz6ojFGXIggGe+ad1odrK9w= -github.com/go-openapi/swag/loading v0.26.1/go.mod h1:3qvRIlWzWdq1HvmldwmuJ2ohpcAryN6xVt2OTKd0/7E= -github.com/go-openapi/swag/mangling v0.26.1 h1:gpYI4WuPKFJJVjV5cDLGlDVJhFIxYjQc7yN5eEb4CqM= -github.com/go-openapi/swag/mangling v0.26.1/go.mod h1:POETDH01hqAdASXfw7ISEd9bCOE6xBHOt8NHmGZRmYM= -github.com/go-openapi/swag/netutils v0.26.0 h1:CmZp+ZT7HrmFwrC3GdGsXBq2+42T1bjKBapcqVpIs3c= -github.com/go-openapi/swag/netutils v0.26.0/go.mod h1:5iK+Ok3ZohWWex1C50BFTPexi03UaPwjW4Oj8kgrpwo= -github.com/go-openapi/swag/stringutils v0.26.1 h1:f88uYyTso7TnHrKM/bUBsQ5e2wKf37cpgo6pvbzd9yU= -github.com/go-openapi/swag/stringutils v0.26.1/go.mod h1:Sc6d3bU8fgk5AyZR8/8jEQ+Is/Ald+TD/IIggPN8UJk= -github.com/go-openapi/swag/typeutils v0.26.1 h1:yg42FgMzRR6PVQ3M3qHz1s+Y6/P4HoJ3cBarXa3OVnU= -github.com/go-openapi/swag/typeutils v0.26.1/go.mod h1:VfnV+oUtSP2vCSCn2aJgnr8OevUYemyIzzS1VOzS10o= -github.com/go-openapi/swag/yamlutils v0.26.1 h1:0TSLK+lXs9vfIhAWzBeI/lOzEnIoot6WTCO1aAeWFTk= -github.com/go-openapi/swag/yamlutils v0.26.1/go.mod h1:7W5b7PRX9MxwL7TjeG7H8HkyBGRsIDRObhyMWFgBI2M= -github.com/go-openapi/testify/enable/yaml/v2 v2.5.1 h1:q9NtHwK4qHF7yZziBPvZyv7zWAIk8ok88Gh2mR6Jpc8= -github.com/go-openapi/testify/enable/yaml/v2 v2.5.1/go.mod h1:JW0MXIotCYps/XsgJnG3a8Q7rE5xAiBwoOD5OfaIQBk= -github.com/go-openapi/testify/v2 v2.5.1 h1:TMdhCaw8fUNraVSf3Omoob1dO/AzBfhtFAPW0an6sBo= -github.com/go-openapi/testify/v2 v2.5.1/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= +github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= +github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= +github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= +github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw= +github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg= +github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q= +github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8= +github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k= +github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU= +github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= +github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4= +github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= +github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU= +github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k= +github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM= +github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k= +github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU= +github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= +github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU= +github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY= +github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= +github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY= +github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= +github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= +github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-playground/webhooks/v6 v6.4.0 h1:KLa6y7bD19N48rxJDHM0DpE3T4grV7GxMy1b/aHMWPY= github.com/go-playground/webhooks/v6 v6.4.0/go.mod h1:5lBxopx+cAJiBI4+kyRbuHrEi+hYRDdRHuRR4Ya5Ums= github.com/go-redis/cache/v9 v9.0.0 h1:0thdtFo0xJi0/WXbRVu8B066z8OvVymXTJGaXrVWnN0= @@ -210,8 +212,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:04sojTxgYxu1L4Hn7Tgf7UVtIosVa6CuHtvNY+7T1K4= github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -231,8 +233,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.29.0 h1:fEG+Ja3YRwNOqnQxTyJwoByAUAvTuxUGiro/jhrm4F4= -github.com/google/cel-go v0.29.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= +github.com/google/cel-go v0.30.0 h1:ll54AkzKunWkBn9wSoiUXbFZXYZTkdJGNXTBXUoolGo= +github.com/google/cel-go v0.30.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -298,8 +300,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= +github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -318,10 +320,10 @@ github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffkt github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= -github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= +github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= +github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -438,8 +440,8 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -451,10 +453,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU= +github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc= +github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= +github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= @@ -483,22 +485,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= -go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= -go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= +go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= +go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= 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/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -509,8 +511,9 @@ go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -518,8 +521,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= @@ -530,8 +533,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= -golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= -golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= +golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= 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= @@ -625,8 +628,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= -golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= @@ -644,17 +647,17 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ= +google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= @@ -677,51 +680,50 @@ gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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 h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= -k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= -k8s.io/apiextensions-apiserver v0.36.1 h1:6JfYmPUsuUIHuN+3QxutXYWj492RqF5fBSx67GYK5Ks= -k8s.io/apiextensions-apiserver v0.36.1/go.mod h1:pLzZin90riwisdzKwv/GoTwENooytoIx5zWJb4Hkby8= -k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA= -k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8= -k8s.io/apiserver v0.36.1 h1:iMS5V+rPUertv5P9RaqJgmHHTuh4quWpoxchvMUY+JY= -k8s.io/apiserver v0.36.1/go.mod h1:Cby1PbLWztu0GDOxoO6iFOyyqIsziHNEW+w9zVQ22Kw= -k8s.io/cli-runtime v0.36.1 h1:yuC/BGnnj1YYPh6D1P+pZnzinCs6DvMq86yAeNqoqzM= -k8s.io/cli-runtime v0.36.1/go.mod h1:ZQWHGt8xAF7KnviB79vX0lYNyUUqKIpU+LQg7exuFAw= -k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0= -k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU= -k8s.io/component-base v0.36.1 h1:iG6GsELftXqTNG9HG6kiVjatSgAw1sf5pJ6R5a6N0kA= -k8s.io/component-base v0.36.1/go.mod h1:nf9XPlntRdqO6WMeEWAA5F93Y4ICZQdeT9GeqLDB3JI= -k8s.io/component-helpers v0.36.1 h1:BTrr5fzNSm8TkQfXrKT3N9ioWwiC4n2FTIwGTUo/ccg= -k8s.io/component-helpers v0.36.1/go.mod h1:s38HnzKQRurbUnhI5IV8GwyL/a3lVuNCYZMTd+rITMM= -k8s.io/controller-manager v0.36.1 h1:d1ifPnAe3FFSnnvcDQiM93bGroFT1lF72GEBKsl+cbg= -k8s.io/controller-manager v0.36.1/go.mod h1:jeJUuFlgbgohGJWrm59Wdlgo3WqxssWXgD2sU6HG/Vo= +k8s.io/api v0.36.4 h1:RxrvqCL6vgH5/+UnTeu1IIFqYmGfy0hnyrod1rn35Oo= +k8s.io/api v0.36.4/go.mod h1:S2B3orCFBDhrgyWbLeuKcT2QdHIpQesBkCYSlWtwUOw= +k8s.io/apiextensions-apiserver v0.36.4 h1:SfvCVt+4CqKWvzuVytYDT5g9hyb9MztoiYELIkPVrFc= +k8s.io/apiextensions-apiserver v0.36.4/go.mod h1:JT9V2Ju7ys1FY4zbSpmX9XOvKB3/BwsODc4hFQEa+Xo= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= +k8s.io/apiserver v0.36.4 h1:AtKjaf2eUiX5G6TfF2IOlhuUuvMsHh49Ivr1+4fZ2gA= +k8s.io/apiserver v0.36.4/go.mod h1:RyiGghXP67hb0Ll+7iLJ6GGv2JpEzCn7ljbiA+L3cJ0= +k8s.io/cli-runtime v0.36.4 h1:OHvManCwP1k9GiC5tXRFxHhzZIQQFCsrHlt7OspKo3w= +k8s.io/cli-runtime v0.36.4/go.mod h1:qQSj2FJgQos6GHpS/ge7wTdQMZm9XFWlesWgV6h7qZY= +k8s.io/client-go v0.36.4 h1:MDvfDNvMSt0Br94SK8neviVlwL9qifw9B26hJCpD1K0= +k8s.io/client-go v0.36.4/go.mod h1:pNK4WKELbwlEDvtbE8l22lEZL5THYF61H5EealokZmA= +k8s.io/component-base v0.36.4 h1:tz75yC2xgq3kd7vPdBtR8do5iMx0OHf6Zd1kuaxDB84= +k8s.io/component-base v0.36.4/go.mod h1:DCwb306U8ou89NNAp45Csuy8ok+1rp1ELDVPhzN5AWc= +k8s.io/component-helpers v0.36.4 h1:B5+SnptAlwTVJO0MW1JLsZVp4KevlADRg0CX5YFzjbU= +k8s.io/component-helpers v0.36.4/go.mod h1:RECUDkRdVuxcNOAl9/EK7lmy1TIjoWkBHs6f0uOyoCs= +k8s.io/controller-manager v0.36.4 h1:YG03tVDUY+BGLRTsNKY0Vms3lsCdq/314DW3IGZfZig= +k8s.io/controller-manager v0.36.4/go.mod h1:63s+JKgdrkqQl3AI2PovT22YMaiXC1i80/LRGLlFVjo= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-aggregator v0.36.1 h1:IzNeRsJcTtgsiCyTgCR1pSwWCrXC1QZQWMTcBw18cFQ= -k8s.io/kube-aggregator v0.36.1/go.mod h1:ROrIm5irUhVUJsKVCgBAAcXpK5IiqpdCn0Ka7LYMGs4= -k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288 h1:A7Lby6ekC6nv+6oO38huCMFBRP0Os+tIeq1GkwxOQes= -k8s.io/kube-openapi v0.0.0-20260519202549-bbf5c5577288/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= -k8s.io/kubectl v0.36.1 h1:96HqS9twIdHM0MlJLTwbo14b9kUKPkOzZ4tlRDLv4qI= -k8s.io/kubectl v0.36.1/go.mod h1:/DGPAIewKsFWF9VFgGvkPhao2Ev4SNuE3BioZo8yPbk= -k8s.io/kubelet v0.36.1 h1:FcHiG9wv92xerRPNxztuhYWqwS4IilOQNPxTPQewYgo= -k8s.io/kubelet v0.36.1/go.mod h1:e6IeoCwqc2TbneCKu6P8HjmWLi7U6SOh3Pocs32iGFM= +k8s.io/kube-aggregator v0.36.4 h1:B593UGiOA2ivyuWOSvgWly5lXkTPLcYpeZwkq4Y+ieA= +k8s.io/kube-aggregator v0.36.4/go.mod h1:05q7hjy8iKStLM1e+BOQ8mMVPnIfAqfpkhZDPGxS0xY= +k8s.io/kube-openapi v0.0.0-20260706235625-cdb1db5517a0 h1:CVjOUCTXINUThEmDs25FNSna0+vnGSoTleN+wiJu6hE= +k8s.io/kube-openapi v0.0.0-20260706235625-cdb1db5517a0/go.mod h1:rcZ+P5cEvHQB+m154WBOatIGBgOEPjzmLkXjkHfg3ms= +k8s.io/kubectl v0.36.4 h1:xZd9g1bFBd7hpb1oKjK8lT9jRL18dtgr4DAPQG1Oksk= +k8s.io/kubectl v0.36.4/go.mod h1:STWlr78cdEa1hHpr55wpcboaqchvfDueKRNDa1zOd1w= +k8s.io/kubelet v0.36.4 h1:mlmXnkrq3H02r/r0H/8M2jdPY7f4I4u4cA0tHnsPzY0= +k8s.io/kubelet v0.36.4/go.mod h1:jcOhk4E8cdUBn7WswW67WH9waQTe37G057ttnYdcaKY= k8s.io/kubernetes v1.36.1 h1:Mt7NKigaZ2KmOmCLhX81lGlH9JU5wjXnYhXnxAun9XA= k8s.io/kubernetes v1.36.1/go.mod h1:MLdeJ3qw2CWH9BFml5GvptxQVQckz54fJOZ/WuixpFE= -k8s.io/streaming v0.36.1 h1:L+K68n4Gg940BGNNYtUBvL1WTLL0YnKT3s+P1MNAmR4= -k8s.io/streaming v0.36.1/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/streaming v0.36.4 h1:RS5YlhrdBN2pKGVjgygGntdu6SNdsduyjGWGe3cX0vo= +k8s.io/streaming v0.36.4/go.mod h1:tJ6S2bZa2HxIBauguBbCWSCYyd93Grfz1+z3tcOvlDE= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= +k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= oras.land/oras-go/v2 v2.6.2 h1:N04RXngAp1LJKTG6ifz3xHPipasEkWr+hFmInja5YKo= oras.land/oras-go/v2 v2.6.2/go.mod h1:PlTtg4JTDJkDe8yVHpM2wz7/YDc00GVas+i4jAW2TZ4= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0 h1:/YpDJ4vReG7ZmzSpBGxduXgywWkJU9zHubgJG03MT+Y= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.36.0/go.mod h1:tJo1aepTXyR+8Xs3sUsGBDk4Ub2AM5dPAPKJx0mpm5c= sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/gateway-api v1.5.0 h1:duoo14Ky/fJXpjpmyMISE2RTBGnfCg8zICfTYLTnBJA= @@ -734,7 +736,7 @@ sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7 sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= -sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/test/openshift/e2e/ginkgo/fixture/agent/fixture.go b/test/openshift/e2e/ginkgo/fixture/agent/fixture.go index 22589ff840b..f51585f7b1a 100644 --- a/test/openshift/e2e/ginkgo/fixture/agent/fixture.go +++ b/test/openshift/e2e/ginkgo/fixture/agent/fixture.go @@ -6,16 +6,13 @@ import ( "crypto/rand" "crypto/rsa" "crypto/x509" - "crypto/x509/pkix" "encoding/base64" "encoding/json" "encoding/pem" "fmt" - "math/big" "net" "sort" "strings" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -32,11 +29,14 @@ import ( argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture" + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/certutil" k8sFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/k8s" osFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/os" "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils" ) +const caSubject = "argocd-agent-ca" + type PrincipalResources struct { PrincipalNamespaceName string ArgoCDAgentPrincipalName string @@ -112,7 +112,6 @@ type VerifyExpectedResourcesExistParams struct { } func VerifyResourcesDeleted(resources PrincipalResources) { - By("verifying resources are deleted for principal pod") Eventually(resources.ServiceAccount).Should(k8sFixture.NotExistByName()) @@ -159,8 +158,8 @@ func CreateRequiredSecrets(cfg PrincipalSecretsConfig) { } Expect(k8sClient.Create(ctx, jwtSecret)).To(Succeed()) - caKey, caCert, caCertPEM := generateCertificateAuthority() - caKeyPEM := encodePrivateKeyToPEM(caKey) + caKey, caCert, caCertPEM := certutil.GenerateCertificateAuthority(caSubject) + caKeyPEM := certutil.EncodePrivateKeyToPEM(caKey) caSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -177,7 +176,7 @@ func CreateRequiredSecrets(cfg PrincipalSecretsConfig) { Expect(k8sClient.Create(ctx, caSecret)).To(Succeed()) principalDNS, principalIPs := aggregateSANs(cfg.PrincipalNamespaceName, cfg.PrincipalServiceName, cfg.AdditionalPrincipalSANs) - principalCertPEM, principalKeyPEM := issueCertificate(caCert, caKey, certificateRequest{ + principalCertPEM, principalKeyPEM := certutil.IssueCertificate(caCert, caKey, certutil.CertificateRequest{ CommonName: cfg.PrincipalServiceName, DNSNames: principalDNS, IPAddresses: principalIPs, @@ -186,7 +185,7 @@ func CreateRequiredSecrets(cfg PrincipalSecretsConfig) { createTLSSecret(ctx, k8sClient, cfg.PrincipalNamespaceName, cfg.PrincipalTLSSecretName, principalCertPEM, principalKeyPEM, caCertPEM) resourceProxyDNS, resourceProxyIPs := aggregateSANs(cfg.PrincipalNamespaceName, cfg.ResourceProxyServiceName, cfg.AdditionalResourceProxySANs) - resourceProxyCertPEM, resourceProxyKeyPEM := issueCertificate(caCert, caKey, certificateRequest{ + resourceProxyCertPEM, resourceProxyKeyPEM := certutil.IssueCertificate(caCert, caKey, certutil.CertificateRequest{ CommonName: cfg.ResourceProxyServiceName, DNSNames: resourceProxyDNS, IPAddresses: resourceProxyIPs, @@ -219,7 +218,7 @@ func CreateRequiredAgentSecrets(cfg AgentSecretsConfig) { caKey := parsePrivateKey(caKeyPEM) clientDNS, clientIPs := aggregateClientSANs(cfg.ClientDNSNames) - clientCertPEM, clientKeyPEM := issueCertificate(caCert, caKey, certificateRequest{ + clientCertPEM, clientKeyPEM := certutil.IssueCertificate(caCert, caKey, certutil.CertificateRequest{ CommonName: cfg.ClientCommonName, DNSNames: clientDNS, IPAddresses: clientIPs, @@ -393,62 +392,6 @@ func VerifyLogs(deploymentName, namespace string, requiredMessages []string) { }, "120s", "5s").Should(BeTrue(), "Agent should process cluster cache updates") } -type certificateRequest struct { - CommonName string - DNSNames []string - IPAddresses []net.IP - ExtKeyUsage []x509.ExtKeyUsage -} - -func generateCertificateAuthority() (*rsa.PrivateKey, *x509.Certificate, []byte) { - privateKey, err := rsa.GenerateKey(rand.Reader, 2048) - Expect(err).ToNot(HaveOccurred()) - - template := x509.Certificate{ - SerialNumber: randomSerialNumber(), - Subject: pkix.Name{CommonName: "argocd-agent-ca"}, - NotBefore: time.Now().Add(-1 * time.Hour), - NotAfter: time.Now().Add(24 * time.Hour), - KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, - BasicConstraintsValid: true, - IsCA: true, - } - - certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) - Expect(err).ToNot(HaveOccurred()) - - cert, err := x509.ParseCertificate(certDER) - Expect(err).ToNot(HaveOccurred()) - - return privateKey, cert, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) -} - -func issueCertificate(caCert *x509.Certificate, caKey *rsa.PrivateKey, req certificateRequest) ([]byte, []byte) { - key, err := rsa.GenerateKey(rand.Reader, 2048) - Expect(err).ToNot(HaveOccurred()) - - template := x509.Certificate{ - SerialNumber: randomSerialNumber(), - Subject: pkix.Name{ - CommonName: req.CommonName, - }, - NotBefore: time.Now().Add(-1 * time.Hour), - NotAfter: time.Now().Add(24 * time.Hour), - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, - ExtKeyUsage: req.ExtKeyUsage, - DNSNames: req.DNSNames, - IPAddresses: req.IPAddresses, - } - - certDER, err := x509.CreateCertificate(rand.Reader, &template, caCert, &key.PublicKey, caKey) - Expect(err).ToNot(HaveOccurred()) - - certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) - keyPEM := encodePrivateKeyToPEM(key) - - return certPEM, keyPEM -} - func createTLSSecret(ctx context.Context, k8sClient client.Client, namespace, secretName string, certPEM, keyPEM, caCertPEM []byte) { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -475,13 +418,6 @@ func generateJWTSigningKey() []byte { return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER}) } -func encodePrivateKeyToPEM(key *rsa.PrivateKey) []byte { - keyDER, err := x509.MarshalPKCS8PrivateKey(key) - Expect(err).ToNot(HaveOccurred()) - - return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER}) -} - func parseCertificate(certPEM []byte) *x509.Certificate { block, _ := pem.Decode(certPEM) Expect(block).ToNot(BeNil(), "invalid certificate data") @@ -501,13 +437,6 @@ func parsePrivateKey(keyPEM []byte) *rsa.PrivateKey { return privateKey } -func randomSerialNumber() *big.Int { - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - Expect(err).ToNot(HaveOccurred()) - return serialNumber -} - func aggregateSANs(namespace, serviceName string, additional []string) ([]string, []net.IP) { defaults := buildDefaultSANs(serviceName, namespace) return aggregateSANLists(defaults, additional) diff --git a/test/openshift/e2e/ginkgo/fixture/certutil/fixture.go b/test/openshift/e2e/ginkgo/fixture/certutil/fixture.go new file mode 100644 index 00000000000..70120b9ac77 --- /dev/null +++ b/test/openshift/e2e/ginkgo/fixture/certutil/fixture.go @@ -0,0 +1,84 @@ +package certutil + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "math/big" + "net" + "time" + + . "github.com/onsi/gomega" +) + +type CertificateRequest struct { + CommonName string + DNSNames []string + IPAddresses []net.IP + ExtKeyUsage []x509.ExtKeyUsage +} + +func GenerateCertificateAuthority(subject string) (*rsa.PrivateKey, *x509.Certificate, []byte) { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + Expect(err).ToNot(HaveOccurred()) + + template := x509.Certificate{ + SerialNumber: randomSerialNumber(), + Subject: pkix.Name{CommonName: subject}, + NotBefore: time.Now().Add(-1 * time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + BasicConstraintsValid: true, + IsCA: true, + } + + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) + Expect(err).ToNot(HaveOccurred()) + + cert, err := x509.ParseCertificate(certDER) + Expect(err).ToNot(HaveOccurred()) + + return privateKey, cert, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) +} + +func IssueCertificate(caCert *x509.Certificate, caKey *rsa.PrivateKey, req CertificateRequest) ([]byte, []byte) { + key, err := rsa.GenerateKey(rand.Reader, 2048) + Expect(err).ToNot(HaveOccurred()) + + template := x509.Certificate{ + SerialNumber: randomSerialNumber(), + Subject: pkix.Name{ + CommonName: req.CommonName, + }, + NotBefore: time.Now().Add(-1 * time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + ExtKeyUsage: req.ExtKeyUsage, + DNSNames: req.DNSNames, + IPAddresses: req.IPAddresses, + } + + certDER, err := x509.CreateCertificate(rand.Reader, &template, caCert, &key.PublicKey, caKey) + Expect(err).ToNot(HaveOccurred()) + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}) + keyPEM := EncodePrivateKeyToPEM(key) + + return certPEM, keyPEM +} + +func randomSerialNumber() *big.Int { + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + Expect(err).ToNot(HaveOccurred()) + return serialNumber +} + +func EncodePrivateKeyToPEM(key *rsa.PrivateKey) []byte { + keyDER, err := x509.MarshalPKCS8PrivateKey(key) + Expect(err).ToNot(HaveOccurred()) + + return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER}) +} diff --git a/test/openshift/e2e/ginkgo/fixture/promoter/fixture.go b/test/openshift/e2e/ginkgo/fixture/promoter/fixture.go new file mode 100644 index 00000000000..bf7e846901c --- /dev/null +++ b/test/openshift/e2e/ginkgo/fixture/promoter/fixture.go @@ -0,0 +1,191 @@ +// promoterFixture provides helpful functions for the GitOps Promoter E2E tests +package promoterFixture + +import ( + "context" + "crypto/x509" + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/certutil" + k8sFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/k8s" + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils" +) + +const caSubject = "gitops-promoter-ca" + +type PromoterAPIServerTLSSecretConfig struct { + PromoterNamespace string + APIServerCertSecretName string + APIServerServiceName string + CABundleSecretName string + CABundleSecretKey string +} + +type VerifyExpectedResourcesExistParams struct { + Namespace *corev1.Namespace + Deployment *appsv1.Deployment + Service *corev1.Service + ControllerConfiguration *promoter.ControllerConfiguration + ClusterRoleNames []string + ClusterRoleBindingNames []string + RoleBinding *rbacv1.RoleBinding + ServiceAccount *corev1.ServiceAccount + APIService *apiregistrationv1.APIService +} + +func CreateAPIServerTLSSecrets(cfg PromoterAPIServerTLSSecretConfig) { + k8sClient, _ := utils.GetE2ETestKubeClient() + ctx := context.Background() + + By("Creating API Server TLS secrets") + + caKey, caCert, caCertPEM := certutil.GenerateCertificateAuthority(caSubject) + caBundleSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cfg.CABundleSecretName, + Namespace: cfg.PromoterNamespace, + }, + Data: map[string][]byte{ + cfg.CABundleSecretKey: caCertPEM, + }, + } + Expect(k8sClient.Create(ctx, caBundleSecret)).To(Succeed()) + + apiServerCertPEM, apiServerKeyPEM := certutil.IssueCertificate(caCert, caKey, certutil.CertificateRequest{ + CommonName: cfg.APIServerServiceName, + DNSNames: []string{ + cfg.APIServerServiceName, + fmt.Sprintf("%s.%s", cfg.APIServerServiceName, cfg.PromoterNamespace), + fmt.Sprintf("%s.%s.svc", cfg.APIServerServiceName, cfg.PromoterNamespace), + fmt.Sprintf("%s.%s.svc.cluster.local", cfg.APIServerServiceName, cfg.PromoterNamespace), + }, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + }) + apiServerTLSSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: cfg.APIServerCertSecretName, + Namespace: cfg.PromoterNamespace, + }, + Type: corev1.SecretTypeTLS, + Data: map[string][]byte{ + "tls.crt": apiServerCertPEM, + "tls.key": apiServerKeyPEM, + "ca.crt": caCertPEM, + }, + } + Expect(k8sClient.Create(ctx, apiServerTLSSecret)).To(Succeed()) +} + +func VerifyExpectedResourcesExist(resources VerifyExpectedResourcesExistParams) { + By("Verifying the expected resources exist") + + if resources.Deployment != nil { + Eventually(resources.Deployment).Should(k8sFixture.ExistByName()) + } + + if resources.Service != nil { + Eventually(resources.Service).Should(k8sFixture.ExistByName()) + } + + if resources.ControllerConfiguration != nil { + Eventually(resources.ControllerConfiguration).Should(k8sFixture.ExistByName()) + } + + if resources.RoleBinding != nil { + Eventually(resources.RoleBinding).Should(k8sFixture.ExistByName()) + } + + if resources.ServiceAccount != nil { + Eventually(resources.ServiceAccount).Should(k8sFixture.ExistByName()) + } + + for _, clusterRoleName := range resources.ClusterRoleNames { + if clusterRoleName == "" { + continue + } + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleName, + }, + } + Eventually(clusterRole).Should(k8sFixture.ExistByName()) + } + + for _, clusterRoleBindingName := range resources.ClusterRoleBindingNames { + if clusterRoleBindingName == "" { + continue + } + clusterRoleBinding := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleBindingName, + }, + } + Eventually(clusterRoleBinding).Should(k8sFixture.ExistByName()) + } + + if resources.APIService != nil { + Eventually(resources.APIService).Should(k8sFixture.ExistByName()) + } +} + +func VerifyExpectedResourcesDontExist(resources VerifyExpectedResourcesExistParams) { + By("Verifying the expected resources don't exist") + + if resources.Deployment != nil { + Eventually(resources.Deployment).Should(k8sFixture.NotExistByName()) + } + + if resources.Service != nil { + Eventually(resources.Service).Should(k8sFixture.NotExistByName()) + } + + if resources.ControllerConfiguration != nil { + Eventually(resources.ControllerConfiguration).Should(k8sFixture.NotExistByName()) + } + + if resources.RoleBinding != nil { + Eventually(resources.RoleBinding).Should(k8sFixture.NotExistByName()) + } + + if resources.ServiceAccount != nil { + Eventually(resources.ServiceAccount).Should(k8sFixture.NotExistByName()) + } + + for _, clusterRoleName := range resources.ClusterRoleNames { + if clusterRoleName == "" { + continue + } + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleName, + }, + } + Eventually(clusterRole).Should(k8sFixture.NotExistByName()) + } + + for _, clusterRoleBindingName := range resources.ClusterRoleBindingNames { + if clusterRoleBindingName == "" { + continue + } + clusterRoleBinding := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleBindingName, + }, + } + Eventually(clusterRoleBinding).Should(k8sFixture.NotExistByName()) + } + + if resources.APIService != nil { + Eventually(resources.APIService).Should(k8sFixture.NotExistByName()) + } +} diff --git a/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go b/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go new file mode 100644 index 00000000000..30cdc738f5b --- /dev/null +++ b/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go @@ -0,0 +1,479 @@ +/* +Copyright 2026. + +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 sequential + +import ( + "context" + "fmt" + "reflect" + + promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" + + argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture" + argoCDFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/argocd" + deploymentFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/deployment" + k8sFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/k8s" + promoterFixture "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/promoter" + fixtureUtils "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils" +) + +const ( + promoterControllerResourceName = "test-promoter-controller-manager" + promoterAPIServerResourceName = "test-promoter-apiserver" + promoterControllerResourceNameWithNamespace = "test-%s-promoter-controller-manager" + promoterAPIServerResourceNameWithNamespace = "test-%s-promoter-apiserver" + apiServerTLSSecretName = "test-tls-secret" + apiServerCABundleSecretName = "test-cabundle-secret" + apiServerCABundleSecretKey = "ca.crt" +) + +var _ = Describe("GitOps Operator Sequential E2E Tests", func() { + Context("1-134_validate_gitops_promoter", func() { + const ( + argoCDName = "test" + ) + + var ( + k8sClient client.Client + ctx context.Context + argoCD *argov1beta1api.ArgoCD + ns *corev1.Namespace + cleanupFunc func() + + controllerServiceAccount *corev1.ServiceAccount + controllerDeployment *appsv1.Deployment + controllerService *corev1.Service + controllerConfig *promoter.ControllerConfiguration + controllerClusterRoleBindingNames []string + controllerClusterRoleNames []string + + apiServerServiceAccount *corev1.ServiceAccount + apiServerDeployment *appsv1.Deployment + apiServerService *corev1.Service + apiServerClusterRoleBindingNames []string + apiServerClusterRoleNames []string + apiServerAPIService *apiregistrationv1.APIService + apiServerRoleBinding *rbacv1.RoleBinding + ) + + BeforeEach(func() { + fixture.EnsureSequentialCleanSlate() + k8sClient, _ = fixtureUtils.GetE2ETestKubeClient() + ctx = context.Background() + ns, cleanupFunc = fixture.CreateNamespaceWithCleanupFunc("gitops-promoter-1-134") + + // Deploy an ArgoCD CR with only the Promoter enabled and nothing else + argoCD = &argov1beta1api.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: argoCDName, + Namespace: ns.Name, + }, + Spec: argov1beta1api.ArgoCDSpec{ + Promoter: &argov1beta1api.PromoterSpec{ + Enabled: ptr.To(true), + }, + Controller: argov1beta1api.ArgoCDApplicationControllerSpec{ + Enabled: ptr.To(false), + }, + Server: argov1beta1api.ArgoCDServerSpec{ + Enabled: ptr.To(false), + }, + Repo: argov1beta1api.ArgoCDRepoSpec{ + Enabled: ptr.To(false), + }, + Redis: argov1beta1api.ArgoCDRedisSpec{ + Enabled: ptr.To(false), + }, + }, + } + + controllerClusterScopedName := fmt.Sprintf(promoterControllerResourceNameWithNamespace, ns.Name) + apiServerClusterScopedName := fmt.Sprintf(promoterAPIServerResourceNameWithNamespace, ns.Name) + + controllerServiceAccount = &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterControllerResourceName, + Namespace: ns.Name, + }, + } + + apiServerServiceAccount = &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterAPIServerResourceName, + Namespace: ns.Name, + }, + } + + controllerDeployment = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterControllerResourceName, + Namespace: ns.Name, + }, + } + + apiServerDeployment = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterAPIServerResourceName, + Namespace: ns.Name, + }, + } + + controllerService = &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterControllerResourceName, + Namespace: ns.Name, + }, + } + + apiServerService = &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: promoterAPIServerResourceName, + Namespace: ns.Name, + }, + } + + controllerConfig = &promoter.ControllerConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "promoter-controller-configuration", + Namespace: ns.Name, + }, + } + + controllerClusterRoleNames = []string{controllerClusterScopedName} + controllerClusterRoleBindingNames = []string{controllerClusterScopedName} + + apiServerClusterRoleNames = []string{apiServerClusterScopedName, apiServerClusterScopedName + "-promotionstrategydetails-viewer"} + apiServerClusterRoleBindingNames = []string{apiServerClusterScopedName, apiServerClusterScopedName + "-promotionstrategydetails-viewer", apiServerClusterScopedName + "-auth-delegator"} + + apiServerAPIService = &apiregistrationv1.APIService{ + ObjectMeta: metav1.ObjectMeta{ + Name: "v1alpha1.view.promoter.argoproj.io", + }, + } + apiServerRoleBinding = &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: apiServerClusterScopedName + "-extension-auth-reader", + Namespace: "kube-system", + }, + } + }) + + AfterEach(func() { + By("Cleaning up namespace") + if cleanupFunc != nil { + cleanupFunc() + } + }) + + createAPIServerTLSSecrets := func(namespace *corev1.Namespace) { + promoterFixture.CreateAPIServerTLSSecrets(promoterFixture.PromoterAPIServerTLSSecretConfig{ + PromoterNamespace: namespace.Name, + APIServerCertSecretName: apiServerTLSSecretName, + APIServerServiceName: promoterAPIServerResourceName, + CABundleSecretName: apiServerCABundleSecretName, + CABundleSecretKey: apiServerCABundleSecretKey, + }) + } + + It("should create all controller and api server resources when enabled and delete them all when disabled", func() { + By("create Argo CD Instance with Promoter enabled") + + Expect(k8sClient.Create(ctx, argoCD)).To(Succeed()) + + controllerResources := promoterFixture.VerifyExpectedResourcesExistParams{ + Namespace: ns, + Deployment: controllerDeployment, + Service: nil, + ControllerConfiguration: controllerConfig, + ClusterRoleNames: controllerClusterRoleNames, + ClusterRoleBindingNames: controllerClusterRoleBindingNames, + RoleBinding: nil, + ServiceAccount: controllerServiceAccount, + APIService: nil, + } + + apiServerResources := promoterFixture.VerifyExpectedResourcesExistParams{ + Namespace: ns, + Deployment: apiServerDeployment, + Service: apiServerService, + ControllerConfiguration: nil, + ClusterRoleNames: apiServerClusterRoleNames, + ClusterRoleBindingNames: apiServerClusterRoleBindingNames, + RoleBinding: apiServerRoleBinding, + ServiceAccount: apiServerServiceAccount, + APIService: apiServerAPIService, + } + + By("verify that Controller resources were reconciled") + promoterFixture.VerifyExpectedResourcesExist(controllerResources) + + By("Verify that API Server resources were reconciled") + promoterFixture.VerifyExpectedResourcesExist(apiServerResources) + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.Enabled = ptr.To(false) + }) + + By("Verify that Controller resources were deleted") + promoterFixture.VerifyExpectedResourcesDontExist(controllerResources) + + By("Verify that API Server resources were deleted") + promoterFixture.VerifyExpectedResourcesDontExist(apiServerResources) + }) + + It("API server is enabled by default and can be disabled", func() { + By("Create Argo CD Instance with Promoter's API Server enabled") + + argoCD.Spec.Promoter.APIServer = &argov1beta1api.PromoterAPIServerSpec{} + argoCD.Spec.Promoter.APIServer.Enabled = ptr.To(true) + Expect(k8sClient.Create(ctx, argoCD)).To(Succeed()) + + apiServerResources := promoterFixture.VerifyExpectedResourcesExistParams{ + Namespace: ns, + Deployment: apiServerDeployment, + Service: apiServerService, + ControllerConfiguration: nil, + ClusterRoleNames: apiServerClusterRoleNames, + ClusterRoleBindingNames: apiServerClusterRoleBindingNames, + RoleBinding: apiServerRoleBinding, + ServiceAccount: apiServerServiceAccount, + APIService: apiServerAPIService, + } + + By("Verify that API Server were created") + promoterFixture.VerifyExpectedResourcesExist(apiServerResources) + + By("Disable API server and verify that the resources are deleted") + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.APIServer = &argov1beta1api.PromoterAPIServerSpec{ + Enabled: ptr.To(false), + } + }) + promoterFixture.VerifyExpectedResourcesDontExist(apiServerResources) + + By("Enable API server again and make sure resources are created again") + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.APIServer = &argov1beta1api.PromoterAPIServerSpec{ + Enabled: ptr.To(true), + } + }) + promoterFixture.VerifyExpectedResourcesExist(apiServerResources) + }) + + It("Webhook resources get created when enabled and are configurable", func() { + By("Create Argo CD Instance without Promoter webhook to ensure its not present by default") + + Expect(k8sClient.Create(ctx, argoCD)).To(Succeed()) + + webhookResources := promoterFixture.VerifyExpectedResourcesExistParams{ + Service: controllerService, + } + promoterFixture.VerifyExpectedResourcesDontExist(webhookResources) + + By("Enable webhook and make sure that the service is created") + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.Webhook = &argov1beta1api.PromoterControllerWebhookSpec{ + Enabled: ptr.To(true), + } + }) + promoterFixture.VerifyExpectedResourcesExist(webhookResources) + + By("Can change the webhook service type in the CR and it gets reflected in the service") + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.Webhook = &argov1beta1api.PromoterControllerWebhookSpec{ + Enabled: ptr.To(true), + ServiceType: "NodePort", + } + }) + Eventually(func() bool { + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(controllerService), controllerService); err != nil { + return false + } + return controllerService.Spec.Type == corev1.ServiceTypeNodePort + }, "60s", "5s").Should(BeTrue()) + + By("Disabling the webhook deletes its resources") + + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter.Webhook = &argov1beta1api.PromoterControllerWebhookSpec{ + Enabled: ptr.To(false), + } + }) + promoterFixture.VerifyExpectedResourcesDontExist(webhookResources) + }) + + It("API Server TLS settings can configured correctly", func() { + By("Create Argo CD Instance where the Promoter's API Server is configured with correct TLS settings") + + argoCD.Spec.Promoter.APIServer = &argov1beta1api.PromoterAPIServerSpec{ + TLS: &argov1beta1api.PromoterAPIServerTLSSpec{ + CABundleSecretName: apiServerCABundleSecretName, + CABundleSecretKey: apiServerCABundleSecretKey, + CertSecretName: apiServerTLSSecretName, + }, + Enabled: ptr.To(true), + } + + createAPIServerTLSSecrets(ns) + Expect(k8sClient.Create(ctx, argoCD)).To(Succeed()) + + By("API Service should have CA Bundle") + Eventually(func() bool { + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(apiServerAPIService), apiServerAPIService); err != nil { + return false + } + + caBundleSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: apiServerCABundleSecretName, + Namespace: ns.Name, + }, + } + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(caBundleSecret), caBundleSecret); err != nil { + return false + } + + return reflect.DeepEqual(apiServerAPIService.Spec.CABundle, caBundleSecret.Data[apiServerCABundleSecretKey]) + }, "60s", "5s").Should(BeTrue()) + + By("API Server's Deployment Volume references correct secret") + Eventually(func() bool { + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(apiServerDeployment), apiServerDeployment); err != nil { + return false + } + + for _, volume := range apiServerDeployment.Spec.Template.Spec.Volumes { + if volume.Secret != nil && volume.Secret.SecretName == apiServerTLSSecretName { + return true + } + } + return false + }, "60s", "5s").Should(BeTrue()) + }) + + It("GitOps Promoter Argo CD UI Extension gets added to the ArgoCD Server Deployment", func() { + argoCD = &argov1beta1api.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: argoCDName, + Namespace: ns.Name, + }, + Spec: argov1beta1api.ArgoCDSpec{ + Promoter: &argov1beta1api.PromoterSpec{ + Enabled: ptr.To(true), + ArgoCDUIExtensionEnabled: true, + }, + }, + } + Expect(k8sClient.Create(ctx, argoCD)).To(Succeed()) + + By("Verifying that the argocd-server exists") + argoCDServer := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-server", + Namespace: ns.Name, + }, + } + Eventually(argoCDServer, "60s", "5s").Should(k8sFixture.ExistByName()) + + By("Verifying that argocd-server has expected extensions volume") + Expect(argoCDServer).Should(deploymentFixture.HaveSpecTemplateSpecVolume(corev1.Volume{ + Name: "argo-cd-operator-ui-extensions", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + })) + + By("verify that the init container is as expected") + initContainer := deploymentFixture.GetTemplateSpecInitContainerByName("promoter-extension", *argoCDServer) + Expect(initContainer).ToNot(BeNil()) + + Expect(initContainer.Image).To(Equal(common.ArgoCDExtensionInstallerImage)) + + Expect(initContainer.Env).To(Equal([]corev1.EnvVar{ + {Name: "EXTENSION_URL", Value: common.GitopsPromoterExtensionURL}, + })) + + By("verify that argocd-server gets the extension volume") + container := deploymentFixture.GetTemplateSpecContainerByName("argocd-server", *argoCDServer) + Expect(container).ToNot(BeNil()) + + expectedVolumeMount := corev1.VolumeMount{ + Name: "argo-cd-operator-ui-extensions", + MountPath: "/tmp/extensions/", + } + + match := false + for _, volumeMount := range container.VolumeMounts { + if reflect.DeepEqual(volumeMount, expectedVolumeMount) { + match = true + } + } + Expect(match).To(BeTrue()) + + By("verify that disabling the extension cleans up its settings") + argoCDFixture.Update(argoCD, func(ac *argov1beta1api.ArgoCD) { + ac.Spec.Promoter = &argov1beta1api.PromoterSpec{ + Enabled: ptr.To(true), + ArgoCDUIExtensionEnabled: false, + } + }) + Eventually(argoCDServer, "60s", "5s").Should(k8sFixture.ExistByName()) + + Eventually(func() bool { + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(argoCDServer), argoCDServer); err != nil { + GinkgoWriter.Println(err) + return false + } + return len(argoCDServer.Spec.Template.Spec.InitContainers) == 0 + }).Should(BeTrue()) + + match = false + for _, volume := range argoCDServer.Spec.Template.Spec.Volumes { + if volume.Name == "argo-cd-operator-ui-extensions" { + match = true + } + } + Expect(match).To(BeFalse()) + + container = deploymentFixture.GetTemplateSpecContainerByName("argocd-server", *argoCDServer) + Expect(container).ToNot(BeNil()) + + match = false + for _, volumeMount := range container.VolumeMounts { + if volumeMount.Name == "argo-cd-operator-ui-extensions" { + match = true + } + } + Expect(match).To(BeFalse()) + }) + }) +}) From 854f3d8e97b5dbf7e3a72c0c528896050b03bf74 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Tue, 25 Aug 2026 16:42:35 -0400 Subject: [PATCH 02/10] fix: correctly add the new CRs and bump go version in Dockerfile Signed-off-by: Christopher Coco --- Dockerfile | 2 +- ...gitops-operator.clusterserviceversion.yaml | 81 +- ...oter.argoproj.io_argocdcommitstatuses.yaml | 324 +++ ...er.argoproj.io_changetransferpolicies.yaml | 1358 +++++++++++ ...moter.argoproj.io_clusterscmproviders.yaml | 265 +++ .../promoter.argoproj.io_commitstatuses.yaml | 232 ++ ....argoproj.io_controllerconfigurations.yaml | 2078 +++++++++++++++++ ...romoter.argoproj.io_gitcommitstatuses.yaml | 336 +++ .../promoter.argoproj.io_gitrepositories.yaml | 303 +++ ...moter.argoproj.io_promotionstrategies.yaml | 1502 ++++++++++++ .../promoter.argoproj.io_pullrequests.yaml | 315 +++ .../promoter.argoproj.io_revertcommits.yaml | 60 + ...r.argoproj.io_scheduledcommitstatuses.yaml | 458 ++++ .../promoter.argoproj.io_scmproviders.yaml | 264 +++ ...moter.argoproj.io_timedcommitstatuses.yaml | 246 ++ ....argoproj.io_webrequestcommitstatuses.yaml | 862 +++++++ config/crd/kustomization.yaml | 14 + 17 files changed, 8698 insertions(+), 2 deletions(-) create mode 100644 bundle/manifests/promoter.argoproj.io_argocdcommitstatuses.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_changetransferpolicies.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_clusterscmproviders.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_commitstatuses.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_controllerconfigurations.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_gitcommitstatuses.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_gitrepositories.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_promotionstrategies.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_pullrequests.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_revertcommits.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_scheduledcommitstatuses.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_scmproviders.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_timedcommitstatuses.yaml create mode 100644 bundle/manifests/promoter.argoproj.io_webrequestcommitstatuses.yaml diff --git a/Dockerfile b/Dockerfile index 1c12a1d9847..96abef49e0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM golang:1.26.3 as builder +FROM golang:1.26.5 as builder WORKDIR /workspace # Copy the Go Modules manifests diff --git a/bundle/manifests/gitops-operator.clusterserviceversion.yaml b/bundle/manifests/gitops-operator.clusterserviceversion.yaml index 72bfb15b3f6..49161bf6166 100644 --- a/bundle/manifests/gitops-operator.clusterserviceversion.yaml +++ b/bundle/manifests/gitops-operator.clusterserviceversion.yaml @@ -190,7 +190,7 @@ metadata: capabilities: Deep Insights console.openshift.io/plugins: '["gitops-plugin"]' containerImage: quay.io/redhat-developer/gitops-operator - createdAt: "2026-08-25T18:47:12Z" + createdAt: "2026-08-25T20:41:02Z" description: Enables teams to adopt GitOps principles for managing cluster configurations and application delivery across hybrid multi-cluster Kubernetes environments. features.operators.openshift.io/disconnected: "true" @@ -243,6 +243,12 @@ spec: kind: AppProject name: appprojects.argoproj.io version: v1alpha1 + - description: ArgoCDCommitStatus is used as a way to aggregate all the Argo CD + Applications that are being used in a promotion strategy. + displayName: ArgoCDCommitStatus + kind: ArgoCDCommitStatus + name: argocdcommitstatuses.promoter.argoproj.io + version: v1alpha1 - kind: ArgoCD name: argocds.argoproj.io version: v1alpha1 @@ -297,6 +303,12 @@ spec: name: "" version: v1 version: v1beta1 + - description: ChangeTransferPolicy represents a pair hydrated environment branch + pair of the proposed environment branch and the live environment branch. + displayName: ChangeTransferPolicy + kind: ChangeTransferPolicy + name: changetransferpolicies.promoter.argoproj.io + version: v1alpha1 - description: A ClusterAnalysisTemplate is like an AnalysisTemplate,but it is not limited to its namespace. It can be used by any Rollout throughout the cluster. @@ -304,6 +316,22 @@ spec: kind: ClusterAnalysisTemplate name: clusteranalysistemplates.argoproj.io version: v1alpha1 + - description: ClusterScmProvider is a cluster-scoped SCM instance (such as GitHub). + displayName: ClusterSCMProvider + kind: ClusterScmProvider + name: clusterscmproviders.promoter.argoproj.io + version: v1alpha1 + - description: CommitStatus is a thin wrapper for the SCM's commit status API. + displayName: CommitStatus + kind: CommitStatus + name: commitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: ControllerConfiguration is used to configure the behavior of the + promoter. + displayName: ControllerConfiguration + kind: ControllerConfiguration + name: controllerconfigurations.promoter.argoproj.io + version: v1alpha1 - description: An Experiment is limited run of one or more ReplicaSets for the purposes of analysis. Experiments typically run for a pre-determined duration, but can also run indefinitely until stopped. @@ -311,11 +339,22 @@ spec: kind: Experiment name: experiments.argoproj.io version: v1alpha1 + - description: GitCommitStatus evaluates commit data with a custom expression + for promotion gating. + displayName: GitCommitStatus + kind: GitCommitStatus + name: gitcommitstatuses.promoter.argoproj.io + version: v1alpha1 - description: GitopsService is the Schema for the gitopsservices API displayName: Gitops Service kind: GitopsService name: gitopsservices.pipelines.openshift.io version: v1alpha1 + - description: GitRepository represents a single git repository. + displayName: GitRepository + kind: GitRepository + name: gitrepositories.promoter.argoproj.io + version: v1alpha1 - description: ImageUpdater is the Schema for the imageupdaters API displayName: ImageUpdater kind: ImageUpdater @@ -331,6 +370,24 @@ spec: kind: NotificationsConfiguration name: notificationsconfigurations.argoproj.io version: v1alpha1 + - description: PromotionStrategy is the user's interface to controlling how changes + are promoted through their environments. + displayName: PromotionStrategy + kind: PromotionStrategy + name: promotionstrategies.promoter.argoproj.io + version: v1alpha1 + - description: PullRequest represents a thin wrapper around the SCM's pull request + API. + displayName: PullRequest + kind: PullRequest + name: pullrequests.promoter.argoproj.io + version: v1alpha1 + - description: RevertCommit represents a revert commit created to roll back a + promotion. + displayName: RevertCommit + kind: RevertCommit + name: revertcommits.promoter.argoproj.io + version: v1alpha1 - description: A controller for managing Argo Rollouts displayName: RolloutManager kind: RolloutManager @@ -339,6 +396,28 @@ spec: - kind: Rollout name: rollouts.argoproj.io version: v1alpha1 + - description: ScheduledCommitStatus provides calendar-based gating for environment + promotions. + displayName: ScheduledCommitStatus + kind: ScheduledCommitStatus + name: scheduledcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: ScmProvider represents a SCM instance (such as GitHub). + displayName: ScmProvider + kind: ScmProvider + name: scmproviders.promoter.argoproj.io + version: v1alpha1 + - description: TimedCommitStatus provides time-based gating for environment promotions. + displayName: TimedCommitStatus + kind: TimedCommitStatus + name: timedcommitstatuses.promoter.argoproj.io + version: v1alpha1 + - description: WebRequestCommitStatus gates promotions on external HTTP/HTTPS + API validation. + displayName: WebRequestCommitStatus + kind: WebRequestCommitStatus + name: webrequestcommitstatuses.promoter.argoproj.io + version: v1alpha1 description: "Red Hat OpenShift GitOps is a declarative continuous delivery platform based on [Argo CD](https://argoproj.github.io/argo-cd/). It enables teams to adopt GitOps principles for managing cluster configurations and automating secure and diff --git a/bundle/manifests/promoter.argoproj.io_argocdcommitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_argocdcommitstatuses.yaml new file mode 100644 index 00000000000..bd172852b03 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_argocdcommitstatuses.yaml @@ -0,0 +1,324 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: argocdcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ArgoCDCommitStatus + listKind: ArgoCDCommitStatusList + plural: argocdcommitstatuses + singular: argocdcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCDCommitStatus is the Schema for the argocdcommitstatuses + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#argocdcommitstatus + 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: ArgoCDCommitStatusSpec defines the desired state of ArgoCDCommitStatus. + properties: + applicationSelector: + description: ApplicationSelector is a label selector that selects + the Argo CD applications to which this commit status applies. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + key: + default: argocd-health + description: |- + Key is the gate name referenced in the PromotionStrategy's activeCommitStatuses. + When omitted, the CRD default is argocd-health. Set Key explicitly, even if you use the CRD default. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + url: + description: URL generates the URL to use in the CommitStatus, for + example a link to the Argo CD UI. + properties: + options: + description: "Options sets options for the template. Options are + described by\nstrings, either a simple string or \"key=value\". + There can be at\nmost one equals sign in an option string. If + the option string\nis unrecognized or otherwise invalid, Option + panics.\n\nKnown options:\n\nmissingkey: Control the behavior + during execution if a map is\nindexed with a key that is not + present in the map.\n\n\t\"missingkey=default\" or \"missingkey=invalid\"\n\t\tThe + default behavior: Do nothing and continue execution.\n\t\tIf + printed, the result of the index operation is the string\n\t\t\"\".\n\t\"missingkey=zero\"\n\t\tThe operation returns + the zero value for the map type's element.\n\t\"missingkey=error\"\n\t\tExecution + stops immediately with an error." + items: + type: string + type: array + template: + description: |- + Template is a go text template and receives .Environment and .ArgoCDCommitStatus variables. A function called urlQueryEscape + is available to escape url query parameters. The template can be configured with options to control the behavior + during execution if a variable is not present. + + Example: + + {{- $baseURL := "https://dev.argocd.local" -}} + {{- if eq .Environment "environment/development" -}} + {{- $baseURL = "https://dev.argocd.local" -}} + {{- else if eq .Environment "environment/staging" -}} + {{- $baseURL = "https://staging.argocd.local" -}} + {{- else if eq .Environment "environment/production" -}} + {{- $baseURL = "https://prod.argocd.local" -}} + {{- end -}} + {{- $labels := "" -}} + {{- range $key, $value := .ArgoCDCommitStatus.Spec.ApplicationSelector.MatchLabels -}} + {{- $labels = printf "%s%s=%s," $labels $key $value -}} + {{- end -}} + {{ printf "%s/applications?labels=%s" $baseURL (urlQueryEscape $labels) }} + type: string + type: object + required: + - applicationSelector + - promotionStrategyRef + type: object + status: + description: ArgoCDCommitStatusStatus defines the observed state of ArgoCDCommitStatus. + properties: + applicationsSelected: + description: |- + ApplicationsSelected represents the Argo CD applications that are selected by the commit status. + This field is sorted by environment (same order as the referenced PromotionStrategy), then namespace, then name. + items: + description: |- + ApplicationsSelected represents the Argo CD applications that are selected by the commit status. The fields in this + struct are all required, since the controller should always fully construct this information. + properties: + clusterName: + description: |- + ClusterName is the name of the cluster that the application manifest is deployed to. An empty string indicates + the local cluster. There is no minimum length, since the local cluster is represented by an empty string. + type: string + environment: + description: Environment is the syncSource.targetBranch of the + Argo CD application (in effect, its environment). + minLength: 1 + type: string + lastTransitionTime: + description: LastTransitionTime is the last time the phase transitioned. + format: date-time + type: string + name: + description: Name is the name of the Argo CD application. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + namespace: + description: Namespace is the namespace of the Argo CD application. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + phase: + description: Phase is the current phase of the commit status. + enum: + - pending + - success + - failure + type: string + sha: + description: |- + Sha is the commit SHA that the application is synced to. + This field is only populated when the application's sync status is Synced. + When the sync status is OutOfSync or Unknown, this field will be empty because + Status.Sync.Revision may contain a branch name instead of a SHA. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^(|[a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - clusterName + - environment + - name + - namespace + - phase + - sha + type: object + type: array + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_changetransferpolicies.yaml b/bundle/manifests/promoter.argoproj.io_changetransferpolicies.yaml new file mode 100644 index 00000000000..58775c5b202 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_changetransferpolicies.yaml @@ -0,0 +1,1358 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: changetransferpolicies.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ChangeTransferPolicy + listKind: ChangeTransferPolicyList + plural: changetransferpolicies + singular: changetransferpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.active.dry.sha + name: Active Dry Sha + type: string + - jsonPath: .status.proposed.dry.sha + name: Proposed Dry Sha + type: string + - jsonPath: .status.proposed.note.drySha + name: Proposed Note Dry Sha + type: string + - jsonPath: .status.pullRequest.state + name: PR State + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ChangeTransferPolicy is the Schema for the changetransferpolicies + API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#changetransferpolicy + 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: ChangeTransferPolicySpec defines the desired state of ChangeTransferPolicy + properties: + activeBranch: + description: |- + ActiveBranch staging hydrated branch + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + activeCommitStatuses: + description: ActiveCommitStatuses lists the statuses to be monitored + on the active branch + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath is an optional repository subpath for this policy's active state. + When set, hydrator metadata is read from /hydrator.metadata. + minLength: 1 + type: string + autoMerge: + default: true + type: boolean + gitRepositoryRef: + description: RepositoryReference what repository to open the PR on. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + proposedBranch: + description: |- + ProposedBranch staging hydrated branch + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + proposedCommitStatuses: + description: ProposedCommitStatuses lists the statuses to be monitored + on the proposed branch + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + pullRequest: + description: |- + PullRequest configures SCM pull request behavior for this change transfer policy. + Copied from the owning PromotionStrategy by the PromotionStrategy controller. + properties: + labels: + description: Labels configures dynamic SCM labels applied to promotion + pull requests. + properties: + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against + ChangeTransferPolicy status and spec. It must return a list of SCM label name strings. + + Available variables: + - Status: ChangeTransferPolicy status (Proposed/Active commit statuses, branch SHAs, etc.) + - Spec: ChangeTransferPolicy spec (ActiveBranch, ProposedBranch, etc.) + - PromotionStrategy: owning PromotionStrategy spec and status when available + + Each returned label name must satisfy the same validation as PullRequest.spec.labels + (non-empty, max 50 characters, no newlines, max 10 labels, unique). + maxLength: 8192 + minLength: 1 + type: string + required: + - expression + type: object + type: object + required: + - activeBranch + - gitRepositoryRef + - proposedBranch + type: object + status: + description: ChangeTransferPolicyStatus defines the observed state of + ChangeTransferPolicy + properties: + active: + description: Active is the state of the active branch. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses that + are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines the + phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the commit + status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is the + commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, which + is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the git note attached + to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit that was + used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that was used + to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that was used + to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located. + type: string + subject: + description: Subject is the subject line of the dry commit + that was used to hydrate the branch. + type: string + type: object + type: object + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + history: + description: |- + History defines the history of promoted changes done by the ChangeTransferPolicy. You can think of + it as a list of PRs merged by GitOps Promoter. It will not include changes that were manually merged. + The history length is hard-coded to be at most 5 entries. This may change in the future. + History is constructed on a best-effort basis and should be used for informational purposes only. + History is in reverse chronological order (newest is first). + items: + description: History describes a particular change that was promoted + by the ChangeTransferPolicy. + properties: + active: + description: Active is the state of the active branch at the + time the PR was merged. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + proposed: + description: Proposed is the state of the proposed branch at + the time the PR was merged. + properties: + commitStatuses: + description: |- + CommitStatuses is a list of commit statuses that were being monitored for this branch. + This contains the state frozen at the moment the PR was merged. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that + was created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: array + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + proposed: + description: Proposed is the state of the proposed branch. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses that + are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines the + phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the commit + status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is the + commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, which + is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message without + the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the git note attached + to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit that was + used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that was used + to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that was used + to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other commits, + that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the commit + that is related in some way to another commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit message, + excluding the subject line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, formatted + as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where the + commit is located. + type: string + subject: + description: Subject is the subject line of the dry commit + that was used to hydrate the branch. + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that was + created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_clusterscmproviders.yaml b/bundle/manifests/promoter.argoproj.io_clusterscmproviders.yaml new file mode 100644 index 00000000000..3119041ff70 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_clusterscmproviders.yaml @@ -0,0 +1,265 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: clusterscmproviders.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ClusterScmProvider + listKind: ClusterScmProviderList + plural: clusterscmproviders + singular: clusterscmprovider + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterScmProvider is the Schema for the clusterscmproviders + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#clusterscmprovider + 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: ScmProviderSpec defines the desired state of ScmProvider + properties: + azureDevOps: + description: AzureDevOps required configuration for Azure DevOps as + the SCM provider + properties: + domain: + description: Domain is the Azure DevOps domain, such as "dev.azure.com". + If using the default Azure DevOps domain, leave this field empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to dev.azure.com, leave + the field blank + rule: self != "dev.azure.com" + organization: + description: Organization is the Azure DevOps organization name. + maxLength: 50 + minLength: 1 + pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$ + type: string + required: + - organization + type: object + bitbucketCloud: + description: BitbucketCloud required configuration for Bitbucket Cloud + as the SCM provider + type: object + fake: + description: Fake required configuration for Fake as the SCM provider + properties: + domain: + description: Domain is the domain of the fake SCM provider. This + is used for testing purposes. + maxLength: 253 + minLength: 1 + type: string + type: object + forgejo: + description: Forgejo required configuration for Forgejo as the SCM + provider + properties: + domain: + description: |- + Domain is the Forgejo domain, such as "codeberg.org" or "forgejo.mycompany.com". + There is no default domain since Forgejo is not a service like Gitlab or Github. + maxLength: 253 + minLength: 1 + type: string + required: + - domain + type: object + gitea: + description: Gitea required configuration for Gitea as the SCM provider + properties: + domain: + description: |- + Domain is the Gitea domain, such as "gitea.com" or "gitea.mycompany.com". + There is no default domain since Gitea is self-hosted. + minLength: 1 + type: string + required: + - domain + type: object + github: + description: GitHub required configuration for GitHub as the SCM provider + properties: + appID: + description: AppID is the GitHub App ID. + format: int64 + minimum: 0 + type: integer + domain: + description: |- + Domain is the GitHub domain, such as "github.mycompany.com". If using the default GitHub domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to github.com, leave + the field blank + rule: self != "github.com" + installationID: + description: |- + InstallationID is the GitHub App Installation ID. If you want to use this ScmProvider for multiple + GitHub orgs, do not specify this field. The installation ID will be inferred from the repo owner + when needed. + format: int64 + minimum: 0 + type: integer + required: + - appID + type: object + gitlab: + description: GitLab required configuration for GitLab as the SCM provider + properties: + domain: + description: |- + Domain is the GitLab domain, such as "gitlab.mycompany.com". If using the default GitLab domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to gitlab.com, leave + the field blank + rule: self != "gitlab.com" + type: object + secretRef: + description: SecretRef contains the credentials required to auth to + a specific provider + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: ScmProviderStatus defines the observed state of ScmProvider + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_commitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_commitstatuses.yaml new file mode 100644 index 00000000000..bf4536f2221 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_commitstatuses.yaml @@ -0,0 +1,232 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: commitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: CommitStatus + listKind: CommitStatusList + plural: commitstatuses + singular: commitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.labels['promoter\.argoproj\.io/commit-status'] + name: Key + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .status.sha + name: Sha + type: string + - jsonPath: .spec.name + name: Name + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + priority: 1 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: CommitStatus is the Schema for the commitstatuses API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#commitstatus + 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: CommitStatusSpec defines the desired state of CommitStatus + properties: + description: + description: |- + Description is a human-readable description of the commit status. + This is shown in the SCM provider (GitHub, GitLab, etc.) as the commit status description. + Use an action-oriented message to convey that the system is actively working. For example, + "Waiting for approval" instead of "Approval pending." + type: string + gitRepositoryRef: + description: ObjectReference is a reference to an object by name. + It is used to refer to objects in the same namespace. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + name: + description: Name is the name of the commit status. + minLength: 1 + type: string + phase: + default: pending + description: Phase is the state of the commit status. This will be + mapped to the appropriate equivalent in the SCM. + enum: + - pending + - success + - failure + type: string + sha: + description: |- + SHA is the commit SHA to set the status on. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + url: + description: Url is a URL that the user can follow to see more details + about the status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - description + - gitRepositoryRef + - name + - phase + - sha + type: object + status: + description: CommitStatusStatus defines the observed state of CommitStatus + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: Id is the unique identifier of the commit status, set + by the SCM + type: string + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + phase: + default: pending + description: Phase is the state of the commit status. This will be + mapped to the appropriate equivalent in the SCM. + enum: + - pending + - success + - failure + - "" + type: string + sha: + description: |- + Sha is the commit SHA that the status is set on. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_controllerconfigurations.yaml b/bundle/manifests/promoter.argoproj.io_controllerconfigurations.yaml new file mode 100644 index 00000000000..d1931e64d81 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_controllerconfigurations.yaml @@ -0,0 +1,2078 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: controllerconfigurations.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ControllerConfiguration + listKind: ControllerConfigurationList + plural: controllerconfigurations + singular: controllerconfiguration + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ControllerConfiguration is the Schema for the controllerconfigurations + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#controllerconfiguration + 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: |- + ControllerConfigurationSpec defines the desired state of ControllerConfiguration. + + This spec contains the global configuration for all controllers in the promoter system. + Each controller has its own configuration section that specifies WorkQueue settings, + rate limiters, and other controller-specific parameters. All fields should be required, + with defaults set in manifests rather than in code. + properties: + argocdCommitStatus: + description: |- + ArgoCDCommitStatus contains the configuration for the ArgoCDCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + watchLocalApplications: + default: true + description: |- + WatchLocalApplications controls whether the controller monitors Argo CD Applications + in the local cluster. When false, the controller will only watch Applications in remote clusters + configured via kubeconfig secrets. This is useful when the Argo CD Application CRD is not installed + in the local cluster or when all Applications are deployed to remote clusters. + type: boolean + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ArgoCDCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - watchLocalApplications + - workQueue + type: object + changeTransferPolicy: + description: |- + ChangeTransferPolicy contains the configuration for the ChangeTransferPolicy controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ChangeTransferPolicy controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + commitStatus: + description: |- + CommitStatus contains the configuration for the CommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the CommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + gitCommitStatus: + description: |- + GitCommitStatus contains the configuration for the GitCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the GitCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + instanceID: + description: |- + InstanceID scopes which Promoter CRs this install reconciles. When set, only resources + labeled promoter.argoproj.io/instance-id with this exact value enter the informer cache. + When unset (nil), only resources without that label are reconciled. There is no mode that + reconciles labeled and unlabeled resources together. Changing this value rebuilds the + informer cache partition: a single-replica install shuts down and restarts automatically; + HA installs (multiple replicas with leader election) require a rolling restart of all pods. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + promotionStrategy: + description: |- + PromotionStrategy contains the configuration for the PromotionStrategy controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the PromotionStrategy controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + pullRequest: + description: |- + PullRequest contains the configuration for the PullRequest controller, + including WorkQueue settings and pull request template configuration. + properties: + template: + description: |- + Template is the template configuration used to generate pull request titles and descriptions. + Uses Go template syntax with Sprig functions available. + properties: + description: + description: |- + Description is the template used to generate the body/description of the pull request. + Uses Go template syntax with Sprig functions available for string manipulation. + type: string + title: + description: |- + Title is the template used to generate the title of the pull request. + Uses Go template syntax with Sprig functions available for string manipulation. + type: string + required: + - description + - title + type: object + workQueue: + description: |- + WorkQueue contains the work queue configuration for the PullRequest controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - template + - workQueue + type: object + scheduledCommitStatus: + description: |- + ScheduledCommitStatus contains the configuration for the ScheduledCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the ScheduledCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + timedCommitStatus: + description: |- + TimedCommitStatus contains the configuration for the TimedCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the TimedCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + webRequestCommitStatus: + description: |- + WebRequestCommitStatus contains the configuration for the WebRequestCommitStatus controller, + including WorkQueue settings that control reconciliation behavior. + properties: + workQueue: + description: |- + WorkQueue contains the work queue configuration for the WebRequestCommitStatus controller. + This includes requeue duration, maximum concurrent reconciles, and rate limiter settings. + properties: + maxConcurrentReconciles: + description: |- + MaxConcurrentReconciles defines the maximum number of concurrent reconcile operations + that can run for this controller. Higher values increase throughput but consume more + resources. + minimum: 1 + type: integer + rateLimiter: + description: |- + RateLimiter defines the rate limiting strategy for the controller's work queue. + Rate limiting controls how quickly failed reconciliations are retried and helps + prevent overwhelming external APIs or systems. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + maxOf: + description: |- + MaxOf allows combining multiple rate limiters, where the maximum delay from all + limiters is used. This enables sophisticated rate limiting that respects multiple + constraints simultaneously (e.g., both per-item exponential backoff and global rate limits). + items: + description: |- + RateLimiterTypes defines the different algorithms available for rate limiting. + + Exactly one of the three rate limiter types must be specified: + - FastSlow: Quick retry for transient errors, then slower retry for persistent failures + - ExponentialFailure: Standard exponential backoff for repeated failures + - Bucket: Token bucket algorithm for controlling overall request rate + + See https://pkg.go.dev/k8s.io/client-go/util/workqueue for implementation details. + properties: + bucket: + description: |- + Bucket rate limiter uses a token bucket algorithm to control request rate. + Allows bursts while maintaining an average rate limit. + properties: + bucket: + description: |- + Bucket is the maximum number of tokens that can be accumulated in the bucket. + This defines the maximum burst size - how many operations can occur in rapid + succession before rate limiting takes effect. Must be non-negative. + minimum: 0 + type: integer + qps: + description: |- + Qps (queries per second) is the rate at which tokens are added to the bucket. + This defines the sustained rate limit for operations. Must be non-negative. + minimum: 0 + type: integer + required: + - bucket + - qps + type: object + exponentialFailure: + description: |- + ExponentialFailure rate limiter increases delay exponentially with each failure. + Standard approach for backing off when operations fail repeatedly. + properties: + baseDelay: + description: |- + BaseDelay is the initial delay after the first failure. Subsequent failures will exponentially + increase this delay (2x, 4x, 8x, etc.) until MaxDelay is reached. + Format follows Go's time.Duration syntax (e.g., "1s" for 1 second). + type: string + maxDelay: + description: |- + MaxDelay is the maximum delay between retry attempts. Once the exponential backoff reaches + this value, all subsequent retries will use this delay. + Format follows Go's time.Duration syntax (e.g., "1m" for 1 minute). + type: string + required: + - baseDelay + - maxDelay + type: object + fastSlow: + description: |- + FastSlow rate limiter provides fast retries initially, then switches to slow retries. + Useful for quickly retrying transient errors while backing off for persistent failures. + properties: + fastDelay: + description: |- + FastDelay is the delay used for the first MaxFastAttempts retry attempts. + Format follows Go's time.Duration syntax (e.g., "100ms" for 100 milliseconds). + type: string + maxFastAttempts: + description: |- + MaxFastAttempts is the number of retry attempts that use FastDelay before switching to SlowDelay. + Must be at least 1. + minimum: 1 + type: integer + slowDelay: + description: |- + SlowDelay is the delay used for retry attempts after MaxFastAttempts have been exhausted. + Format follows Go's time.Duration syntax (e.g., "10s" for 10 seconds). + type: string + required: + - fastDelay + - maxFastAttempts + - slowDelay + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + maxItems: 3 + type: array + type: object + x-kubernetes-validations: + - message: at most one of the fields in [fastSlow exponentialFailure + bucket maxOf] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket),has(self.maxOf)].filter(x,x==true).size() + <= 1' + - message: at most one of the fields in [fastSlow exponentialFailure + bucket] may be set + rule: '[has(self.fastSlow),has(self.exponentialFailure),has(self.bucket)].filter(x,x==true).size() + <= 1' + requeueDuration: + description: |- + RequeueDuration specifies how frequently resources should be requeued for automatic reconciliation. + This creates a periodic reconciliation loop that ensures the desired state is maintained even + without external triggers. Format follows Go's time.Duration syntax (e.g., "5m" for 5 minutes). + type: string + required: + - maxConcurrentReconciles + - rateLimiter + - requeueDuration + type: object + required: + - workQueue + type: object + required: + - argocdCommitStatus + - changeTransferPolicy + - commitStatus + - gitCommitStatus + - promotionStrategy + - pullRequest + - scheduledCommitStatus + - timedCommitStatus + - webRequestCommitStatus + type: object + status: + description: ControllerConfigurationStatus defines the observed state + of ControllerConfiguration. + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_gitcommitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_gitcommitstatuses.yaml new file mode 100644 index 00000000000..7c10673eddb --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_gitcommitstatuses.yaml @@ -0,0 +1,336 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: gitcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: GitCommitStatus + listKind: GitCommitStatusList + plural: gitcommitstatuses + singular: gitcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.key + name: Key + type: string + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .spec.target + name: Validates + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + GitCommitStatus is the Schema for the gitcommitstatuses API. + + It validates commits from PromotionStrategy environments using configurable expressions + and creates CommitStatus resources with the validation results. + + Use the Target field to control which commit is validated: + - "active" (default): Validates the currently deployed commit + - "proposed": Validates the incoming commit + + The validation result is always reported on the PROPOSED commit to enable promotion gating, + regardless of which commit was validated. + + Workflow: + 1. Controller reads PromotionStrategy to get ProposedHydratedSha and ActiveHydratedSha + 2. Controller selects SHA to validate based on Target field + 3. Controller fetches commit data (subject, body, author, trailers) for selected SHA + 4. Controller evaluates expression against selected commit data + 5. Controller creates/updates CommitStatus with result attached to PROPOSED SHA + 6. PromotionStrategy checks CommitStatus on PROPOSED SHA before allowing promotion + + Common use cases: + - "Ensure active commit is not a revert before promoting" + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#gitcommitstatus + 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: spec defines the desired state of GitCommitStatus + properties: + description: + description: |- + Description is a human-readable description of this validation that will be shown in the SCM provider + (GitHub, GitLab, etc.) as the commit status description. + If not specified, defaults to empty string. + type: string + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against commit data + for environments in the referenced PromotionStrategy. + The expression must return a boolean value where true indicates the validation passed. + + The commit validated is determined by the Target field: + - "active" (default): Validates the ACTIVE (currently deployed) commit + - "proposed": Validates the PROPOSED commit (what will be promoted) + + The validation result is always reported on the PROPOSED commit to enable promotion gating. + + Use Cases by Mode: + Active mode: State-based gating - validate current environment before allowing promotion + - "Don't promote until active commit has required sign-offs" + - "Verify current deployment meets compliance before next promotion" + - "Ensure active commit is not a revert before promoting" + + Proposed mode: Change-based gating - validate the incoming change itself + - "Don't promote unless new commit follows naming convention" + - "Ensure proposed commit has proper JIRA ticket reference" + - "Require specific author for proposed changes" + + Available variables in the expression context: + - Commit.SHA (string): the commit SHA being validated (active or proposed based on Target) + - Commit.Subject (string): the first line of the commit message + - Commit.Body (string): the commit message body (everything after the subject line) + - Commit.Author (string): commit author email address + - Commit.Trailers (map[string][]string): git trailers parsed from commit message + type: string + key: + description: |- + Key is the unique identifier for this validation rule. + It is used as the commit status key and in status messages. + This key is matched against PromotionStrategy's proposedCommitStatuses or activeCommitStatuses + to determine which environments this validation applies to. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: |- + PromotionStrategyRef is a reference to the promotion strategy that this commit status applies to. + The controller will validate commits from ALL environments in the referenced PromotionStrategy + where this GitCommitStatus.Spec.Key matches an entry in either: + - PromotionStrategy.Spec.ProposedCommitStatuses (applies to all environments), OR + - Environment.ProposedCommitStatuses (applies to specific environment) + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + target: + default: active + description: |- + Target specifies which commit SHA to validate with the expression. + - "active": Validates the currently active/deployed commit (default behavior) + - "proposed": Validates the proposed commit that will be promoted + + The validation result is always reported on the PROPOSED commit (for gating), but this field + controls which commit's data is used in the expression evaluation. + + Examples: + target: "active" - "Don't promote if a revert commit is detected" + target: "proposed" - "Don't promote unless new commit follows naming convention" + enum: + - active + - proposed + type: string + required: + - expression + - key + - promotionStrategyRef + type: object + status: + description: status defines the observed state of GitCommitStatus + properties: + conditions: + description: |- + Conditions represent the latest available observations of the GitCommitStatus's state. + Standard condition types include "Ready" which aggregates the status of all environments. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: |- + Environments holds the validation results for each environment where this validation applies. + Each entry corresponds to an environment from the PromotionStrategy where the Key matches + either global or environment-specific proposedCommitStatuses. + + The controller validates the commit specified by Target ("active" or "proposed") + but the CommitStatus is always reported on the PROPOSED commit for promotion gating. + Each environment entry tracks both the ProposedHydratedSha (where status is reported) and the + ActiveHydratedSha, with TargetedSha indicating which one was actually evaluated. + items: + description: GitCommitStatusEnvironmentStatus defines the observed + validation status for a specific environment. + properties: + activeHydratedSha: + description: |- + ActiveHydratedSha is the currently active (deployed) hydrated commit SHA that was validated. + This comes from the PromotionStrategy's environment status. + The expression is evaluated against THIS commit's data, not the proposed commit. + May be empty if the PromotionStrategy hasn't reconciled yet. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + branch: + description: Branch is the environment branch name being validated. + minLength: 1 + type: string + expressionResult: + description: |- + ExpressionResult contains the boolean result of the expression evaluation. + Only set when the expression successfully evaluates to a boolean. + nil indicates the expression has not yet been evaluated, failed to compile, or failed to evaluate. + type: boolean + phase: + description: |- + Phase represents the current validation state of the commit. + - "pending": validation has not completed, commit data is not yet available, or SHAs are empty + - "success": expression evaluated to true, validation passed + - "failure": expression evaluated to false, validation failed, or expression compilation failed + enum: + - pending + - success + - failure + type: string + proposedHydratedSha: + description: |- + ProposedHydratedSha is the proposed hydrated commit SHA where the validation result is reported. + This comes from the PromotionStrategy's environment status. + The CommitStatus resource is created with this SHA, allowing the PromotionStrategy to gate + promotions based on the validation of the ACTIVE commit. + May be empty if the PromotionStrategy hasn't reconciled yet. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + targetedSha: + description: |- + TargetedSha is the commit SHA that was actually validated by the expression. + This will match either ProposedHydratedSha or ActiveHydratedSha depending on + the Target setting ("proposed" or "active"). + This field clarifies which commit's data was used in the expression evaluation. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - branch + - phase + - proposedHydratedSha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_gitrepositories.yaml b/bundle/manifests/promoter.argoproj.io_gitrepositories.yaml new file mode 100644 index 00000000000..21e57010cf1 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_gitrepositories.yaml @@ -0,0 +1,303 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: gitrepositories.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: GitRepository + listKind: GitRepositoryList + plural: gitrepositories + singular: gitrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.scmProviderRef.name + name: Provider + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#gitrepository + 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: GitRepositorySpec defines the desired state of GitRepository + properties: + azureDevOps: + description: AzureDevOpsRepo is a repository in Azure DevOps, identified + by its project and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 64 + minLength: 1 + type: string + project: + description: Project is the project name in Azure DevOps. + maxLength: 64 + minLength: 1 + type: string + required: + - name + - project + type: object + bitbucketCloud: + description: BitbucketCloudRepo is a repository in Bitbucket Cloud, + identified by its owner and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 62 + minLength: 1 + pattern: ^[a-zA-Z0-9_.-]+$ + type: string + owner: + description: Owner is the owner of the repository (can be a user + or workspace). + minLength: 1 + pattern: ^[a-zA-Z0-9_-]+$ + type: string + required: + - name + - owner + type: object + fake: + description: FakeRepo is a placeholder for a repository in the fake + SCM provider, used for testing purposes. + properties: + name: + description: Name is the name of the repository. + minLength: 1 + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + forgejo: + description: ForgejoRepo is a repository in Forgejo, identified by + its owner and name. + properties: + name: + description: Name is the name of the repository. + minLength: 1 + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + gitea: + description: GiteaRepo is a repository in Gitea, identified by its + owner and name. + properties: + name: + description: Name is the name of the repository. + type: string + owner: + description: Owner is the owner of the repository. + minLength: 1 + type: string + required: + - name + - owner + type: object + github: + description: GitHubRepo is a repository in GitHub, identified by its + owner and name. + properties: + name: + description: Name is the name of the repository. + maxLength: 100 + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\.]+$ + type: string + owner: + description: Owner is the owner of the repository, which can be + a user or an organization. + maxLength: 39 + minLength: 1 + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-]*$ + type: string + required: + - name + - owner + type: object + gitlab: + description: GitLabRepo is a repository in GitLab, identified by its + namespace, name, and project ID. + properties: + name: + description: Name is the project slug of the repository. + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\/.]+$ + type: string + namespace: + description: Namespace is the user, group or group with subgroup + (e.g. group/subgroup). + minLength: 1 + pattern: ^[a-zA-Z0-9_\-\/.]+$ + type: string + projectId: + description: ProjectID is the ID of the project in GitLab. + minimum: 0 + type: integer + required: + - name + - namespace + - projectId + type: object + scmProviderRef: + description: ScmProviderObjectReference is a reference to a SCM provider + object. + properties: + kind: + default: ScmProvider + description: Kind is the type of resource being referenced + enum: + - ScmProvider + - ClusterScmProvider + type: string + name: + description: Name is the name of the resource being referenced + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - kind + - name + type: object + required: + - scmProviderRef + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: GitRepositoryStatus defines the observed state of GitRepository + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_promotionstrategies.yaml b/bundle/manifests/promoter.argoproj.io_promotionstrategies.yaml new file mode 100644 index 00000000000..13bf5111a9c --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_promotionstrategies.yaml @@ -0,0 +1,1502 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: promotionstrategies.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: PromotionStrategy + listKind: PromotionStrategyList + plural: promotionstrategies + singular: promotionstrategy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PromotionStrategy is the Schema for the promotionstrategies API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#promotionstrategy + 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: PromotionStrategySpec defines the desired state of PromotionStrategy + properties: + activeCommitStatuses: + description: |- + ActiveCommitStatuses are commit statuses describing an actively running dry commit. If an active commit status + is failing for an environment, subsequent environments will not deploy the failing commit. + + The commit statuses specified in this field apply to all environments in the promotion sequence. You can also + specify commit statuses for individual environments in the `environments` field. + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath is the default repository subpath for this strategy's active state. + When set, proposed branches are created as -next/. + Individual environments can override this value via their own activePath field. + minLength: 1 + type: string + environments: + description: Environments is the sequence of environments that a dry + commit will be promoted through. + items: + description: Environment defines a single environment in the promotion + sequence. + properties: + activeCommitStatuses: + description: |- + ActiveCommitStatuses are commit statuses describing an actively running dry commit. If an active commit status + is failing for an environment, subsequent environments will not deploy the failing commit. + + The commit statuses specified in this field apply to this environment only. You can also specify commit statuses + for all environments in the `spec.activeCommitStatuses` field. + items: + description: CommitStatusSelector is used to select commit + statuses by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + activePath: + description: |- + ActivePath optionally overrides the strategy-level activePath for this environment. + When set, this environment's CTP uses this path instead of spec.activePath. + minLength: 1 + type: string + autoMerge: + default: true + description: |- + AutoMerge determines whether the dry commit should be automatically merged into the next branch in the sequence. + If false, the dry commit will be proposed but not merged. + type: boolean + branch: + description: |- + Branch is the name of the active branch for the environment. + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + proposedCommitStatuses: + description: |- + ProposedCommitStatuses are commit statuses describing a proposed dry commit, i.e. one that is not yet running + in a live environment. If a proposed commit status is failing for a given environment, the dry commit will not + be promoted to that environment. + + The commit statuses specified in this field apply to this environment only. You can also specify commit statuses + for all environments in the `spec.proposedCommitStatuses` field. + items: + description: CommitStatusSelector is used to select commit + statuses by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + required: + - branch + type: object + maxItems: 1000 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + gitRepositoryRef: + description: RepositoryReference indicates what repository to promote + commits in. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + proposedCommitStatuses: + description: |- + ProposedCommitStatuses are commit statuses describing a proposed dry commit, i.e. one that is not yet running + in a live environment. If a proposed commit status is failing for a given environment, the dry commit will not + be promoted to that environment. + + The commit statuses specified in this field apply to all environments in the promotion sequence. You can also + specify commit statuses for individual environments in the `environments` field. + items: + description: CommitStatusSelector is used to select commit statuses + by their key. + properties: + key: + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + required: + - key + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + pullRequest: + description: PullRequest configures SCM pull request behavior for + all environments in this strategy. + properties: + labels: + description: Labels configures dynamic SCM labels applied to promotion + pull requests. + properties: + expression: + description: |- + Expression is evaluated using the expr library (github.com/expr-lang/expr) against + ChangeTransferPolicy status and spec. It must return a list of SCM label name strings. + + Available variables: + - Status: ChangeTransferPolicy status (Proposed/Active commit statuses, branch SHAs, etc.) + - Spec: ChangeTransferPolicy spec (ActiveBranch, ProposedBranch, etc.) + - PromotionStrategy: owning PromotionStrategy spec and status when available + + Each returned label name must satisfy the same validation as PullRequest.spec.labels + (non-empty, max 50 characters, no newlines, max 10 labels, unique). + maxLength: 8192 + minLength: 1 + type: string + required: + - expression + type: object + type: object + required: + - environments + - gitRepositoryRef + type: object + status: + description: PromotionStrategyStatus defines the observed state of PromotionStrategy + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment in + the promotion sequence. + items: + description: EnvironmentStatus defines the observed state of an + environment in a PromotionStrategy. + properties: + active: + description: Active is the state of the active branch for the + environment. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + branch: + description: Branch is the name of the active branch for the + environment. + minLength: 1 + type: string + history: + description: |- + History defines the history of promoted changes done by the PromotionStrategy for each environment. + You can think of it as a list of PRs merged by GitOps Promoter. It will not include changes that were + manually merged. The history length is hard-coded to be at most 5 entries. This may change in the future. + History is constructed on a best-effort basis and should be used for informational purposes only. + History is in reverse chronological order (newest is first). + items: + description: History describes a particular change that was + promoted by the ChangeTransferPolicy. + properties: + active: + description: Active is the state of the active branch + at the time the PR was merged. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase + defines the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description + of the commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status + in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which + is the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the + branch, which is the commit that is currently being + worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + note: + description: Note is the hydrator metadata from the + git note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit + that was used to hydrate the branch without + the subject. + type: string + date: + description: Date is the date of the dry commit + that was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + type: string + subject: + description: Subject is the subject line of the + dry commit that was used to hydrate the branch. + type: string + type: object + type: object + proposed: + description: Proposed is the state of the proposed branch + at the time the PR was merged. + properties: + commitStatuses: + description: |- + CommitStatuses is a list of commit statuses that were being monitored for this branch. + This contains the state frozen at the moment the PR was merged. + items: + description: ChangeRequestPolicyCommitStatusPhase + defines the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description + of the commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status + in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + hydrated: + description: Hydrated is the hydrated state of the + branch, which is the commit that is currently being + worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit + was made + format: date-time + type: string + references: + description: References are the references to + other commits, that went into the hydration + of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about + the commit that is related in some way + to another commit. + properties: + author: + description: Author is the author of + the commit. + type: string + body: + description: Body is the body of the + commit message, excluding the subject + line, i.e. `git show --format=%b`. + type: string + date: + description: Date is the date of the + commit, formatted as by `git show + -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the + repository where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject + line of the commit message, i.e. `git + show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository + where the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the + commit message + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request + that was created for this ChangeTransferPolicy. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull + request, set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull + request was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + type: array + lastHealthyDryShas: + description: LastHealthyDryShas is a list of dry commits that + were observed to be healthy in the environment. + items: + description: HealthyDryShas is a list of dry commits that + were observed to be healthy in the environment. + properties: + sha: + description: |- + Sha is the commit SHA of the dry commit that was observed to be healthy. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + time: + description: Time is the time when the proposed commit + for the given dry SHA was merged into the active branch. + format: date-time + type: string + required: + - sha + - time + type: object + type: array + proposed: + description: Proposed is the state of the proposed branch for + the environment. + properties: + commitStatuses: + description: CommitStatuses is a list of commit statuses + that are being monitored for this branch. + items: + description: ChangeRequestPolicyCommitStatusPhase defines + the phase of a commit status in a ChangeTransferPolicy. + properties: + description: + description: Description is the description of the + commit status + type: string + key: + description: Key staging hydrated branch + maxLength: 63 + minLength: 1 + pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9] + type: string + phase: + description: Phase what phase is the status in + enum: + - pending + - success + - failure + type: string + url: + description: Url is the URL of the commit status + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + required: + - key + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - key + x-kubernetes-list-type: map + dry: + description: Dry is the dry state of the branch, which is + the commit that is being proposed. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + hydrated: + description: Hydrated is the hydrated state of the branch, + which is the commit that is currently being worked on. + properties: + author: + description: Author is the author of the commit + type: string + body: + description: Body is the body of the commit message + without the subject line + type: string + commitTime: + description: CommitTime is the time the commit was made + format: date-time + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the SHA of the commit in the branch + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of the commit + message + type: string + type: object + note: + description: Note is the hydrator metadata from the git + note attached to the hydrated commit. + properties: + author: + description: Author is the author of the dry commit + that was used to hydrate the branch. + type: string + body: + description: Body is the body of the dry commit that + was used to hydrate the branch without the subject. + type: string + date: + description: Date is the date of the dry commit that + was used to hydrate the branch. + format: date-time + type: string + drySha: + description: |- + DrySha is the SHA of the commit that was used as the dry source for hydration. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + references: + description: References are the references to other + commits, that went into the hydration of the branch. + items: + description: |- + RevisionReference contains a reference to a some information that is related in some way to another commit. For now, + it supports only references to a commit. In the future, it may support other types of references. + properties: + commit: + description: Commit contains metadata about the + commit that is related in some way to another + commit. + properties: + author: + description: Author is the author of the commit. + type: string + body: + description: Body is the body of the commit + message, excluding the subject line, i.e. + `git show --format=%b`. + type: string + date: + description: Date is the date of the commit, + formatted as by `git show -s --format=%aI`. + format: date-time + type: string + repoURL: + description: RepoURL is the URL of the repository + where the commit is located. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + sha: + description: |- + Sha is the commit hash. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + subject: + description: Subject is the subject line of + the commit message, i.e. `git show --format=%s`. + type: string + type: object + type: object + type: array + repoURL: + description: RepoURL is the URL of the repository where + the commit is located. + type: string + subject: + description: Subject is the subject line of the dry + commit that was used to hydrate the branch. + type: string + type: object + type: object + pullRequest: + description: PullRequest is the state of the pull request that + was created for this environment. + properties: + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + PullRequest still desired it open: merged or closed outside the controller, or closed on the SCM + because the PullRequest resource was deleted (finalizer) before this status was reconciled. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + This status is preserved even after the PullRequest resource is deleted, maintaining a historical + record until a new pull request is created for this environment. + type: boolean + id: + description: ID is the unique identifier of the pull request, + set by the SCM. + type: string + prCreationTime: + description: PRCreationTime is the time when the pull request + was created. + format: date-time + type: string + prMergeTime: + description: |- + PRMergeTime is the time when the pull request was merged. This time can vary slightly from the actual merge time because + it is the time when the ChangeTransferPolicy controller sets the pull requests spec to merge. In the future we plan on making + this time more accurate by fetching the actual merge time from the SCM via the webhook this would then be updated in the git note + for that commit. + format: date-time + type: string + state: + description: State is the state of the pull request. + enum: + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + required: + - active + - branch + - proposed + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + required: + - environments + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_pullrequests.yaml b/bundle/manifests/promoter.argoproj.io_pullrequests.yaml new file mode 100644 index 00000000000..a3431b10058 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_pullrequests.yaml @@ -0,0 +1,315 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: pullrequests.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: PullRequest + listKind: PullRequestList + plural: pullrequests + singular: pullrequest + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .status.id + name: ID + type: string + - jsonPath: .spec.sourceBranch + name: Source + priority: 1 + type: string + - jsonPath: .spec.targetBranch + name: Target + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.url + name: URL + priority: 1 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PullRequest is the Schema for the pullrequests API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#pullrequest + 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: PullRequestSpec defines the desired state of PullRequest + properties: + commit: + description: Commit contains configuration for how we will merge/squash/etc + the pull request. + properties: + message: + description: Message is the commit message that will be written + for the commit that's made when merging the PR. + type: string + required: + - message + type: object + description: + description: Description is the description body of the pull/merge + request + type: string + gitRepositoryRef: + description: RepositoryReference indicates what repository to open + the PR on. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + labels: + description: |- + Labels is the desired set of SCM pull request labels (not Kubernetes metadata labels). + Written by the ChangeTransferPolicy controller from pullRequest.labels.expression evaluation. + items: + maxLength: 50 + minLength: 1 + pattern: ^[^\n\r\x00]+$ + type: string + maxItems: 10 + type: array + x-kubernetes-list-type: set + mergeSha: + description: |- + MergeSha is the commit SHA that the head branch must match before the PR can be merged. + This prevents a race condition where a PR is merged with a different commit than intended. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + minLength: 40 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + sourceBranch: + description: |- + SourceBranch is the base the git reference that we are merging into Head ---> Base + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: field is immutable + rule: self == oldSelf + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + state: + default: open + description: |- + State of the pull request (closed, merged, or open). Must always be "open" when creating a new pull request. + This value may not be changed to "closed" or "merged" unless the pull request status.id is set. + enum: + - closed + - merged + - open + type: string + targetBranch: + description: |- + TargetBranch is the head the git reference we are merging from Head ---> Base + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: field is immutable + rule: self == oldSelf + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + title: + description: Title is the title of the pull request. + minLength: 1 + type: string + required: + - gitRepositoryRef + - mergeSha + - sourceBranch + - state + - targetBranch + - title + type: object + status: + description: PullRequestStatus defines the observed state of PullRequest + properties: + appliedLabels: + description: AppliedLabels lists SCM labels successfully applied by + gitops-promoter (for sync and retraction). + items: + maxLength: 50 + minLength: 1 + pattern: ^[^\n\r\x00]+$ + type: string + maxItems: 10 + type: array + x-kubernetes-list-type: set + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + externallyMergedOrClosed: + description: |- + ExternallyMergedOrClosed indicates that the pull request is no longer open on the SCM while the + resource still desired it open (spec.state is "open"): either it was merged or closed outside the + controller, or it was closed on the SCM because the PullRequest resource was deleted (finalizer) + and a subsequent sync observed it missing. The controller does not distinguish those cases here. + When true, the State field will be empty ("") since we cannot tell merge vs. close from the provider. + The PullRequest resource will be deleted after this flag is set when possible, but the status is + preserved in the owning ChangeTransferPolicy to maintain a record. + type: boolean + id: + description: ID the id of the pull request + type: string + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + prCreationTime: + description: PRCreationTime the time the PR was created + format: date-time + type: string + scmSyncedSpecDigest: + description: |- + SCMSyncedSpecDigest fingerprints title and description last successfully synced + to the SCM via provider.Update on an open pull request. + type: string + state: + description: State of the merge request closed/merged/open + enum: + - "" + - closed + - merged + - open + type: string + url: + description: Url is the URL of the pull request. + pattern: ^(https?://.*)?$ + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: self == '' || isURL(self) + type: object + type: object + x-kubernetes-validations: + - message: Cannot transition to 'closed' or 'merged' state when status.id + is empty + rule: self.spec.state == 'open' || has(self.status.id) && self.status.id + != "" + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_revertcommits.yaml b/bundle/manifests/promoter.argoproj.io_revertcommits.yaml new file mode 100644 index 00000000000..c7c2a50ac0d --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_revertcommits.yaml @@ -0,0 +1,60 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: revertcommits.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: RevertCommit + listKind: RevertCommitList + plural: revertcommits + singular: revertcommit + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: RevertCommit is the Schema for the revertcommits 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: RevertCommitSpec defines the desired state of RevertCommit + properties: + foo: + description: Foo is an example field of RevertCommit. Edit revertcommit_types.go + to remove/update + type: string + type: object + status: + description: RevertCommitStatus defines the observed state of RevertCommit + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_scheduledcommitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_scheduledcommitstatuses.yaml new file mode 100644 index 00000000000..bb79f1b11b9 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_scheduledcommitstatuses.yaml @@ -0,0 +1,458 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: scheduledcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ScheduledCommitStatus + listKind: ScheduledCommitStatusList + plural: scheduledcommitstatuses + singular: scheduledcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScheduledCommitStatus is the Schema for the scheduledcommitstatuses + API. + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#scheduledcommitstatus + 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: spec defines the desired state of ScheduledCommitStatus + properties: + allow: + description: |- + Allow defines global allow windows applied to all listed environments in addition to + per-environment allow windows (OR semantics across all). + items: + description: CronWindow defines a recurring time window using a + cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + environments: + description: |- + Environments defines the list of environments to gate. Only listed environments are gated; + unlisted environments default to success (24/7 open). Each environment inherits global + allow/exclude windows and may add its own. An environment with no per-environment windows + is valid when global windows are defined. + items: + description: ScheduledEnvironment defines the window configuration + for a single environment. + properties: + allow: + description: |- + Allow defines the allowed promotion windows. Promotions are allowed when the current time + falls inside any of these windows (OR semantics). These are combined with any global + spec.allow windows. If no allow windows are defined (neither here nor globally), the + environment operates in exclusion-only mode. + items: + description: CronWindow defines a recurring time window using + a cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + branch: + description: |- + Branch is the name of the branch/environment you want to gate with time windows. + Must not start with '-', contain ':', or contain '..'. + maxLength: 100 + minLength: 1 + type: string + x-kubernetes-validations: + - message: branch must not start with '-' + rule: '!self.startsWith(''-'')' + - message: branch must not contain ':' + rule: '!self.contains('':'')' + - message: branch must not contain '..' + rule: '!self.contains(''..'')' + exclude: + description: |- + Exclude defines blackout periods during which promotions are blocked. Exclusions take + precedence over allow windows — if the current time falls inside any exclusion, promotions + are blocked regardless of allow windows. These are combined with any global spec.exclude + windows. If empty, no blackout periods are applied. + items: + description: CronWindow defines a recurring time window using + a cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + required: + - branch + type: object + maxItems: 1000 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + exclude: + description: |- + Exclude defines global exclusion windows applied to all listed environments in addition to + per-environment exclusions. Exclusions take precedence over allow windows. + items: + description: CronWindow defines a recurring time window using a + cron expression and a duration. + properties: + cron: + description: |- + Cron is a standard 5-field cron expression defining the start of the window + (minute hour day-of-month month day-of-week). For example "0 9 * * 1-5" means + Monday–Friday at 09:00 in the configured timezone. + maxLength: 256 + minLength: 9 + type: string + description: + description: |- + Description is an optional human-readable explanation of this window + (e.g. "US East business hours", "Holiday deployment freeze"). + maxLength: 256 + type: string + duration: + description: |- + Duration is how long the window remains open after the cron trigger. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "8h", "30m", "2h30m". + type: string + timezone: + description: |- + Timezone overrides the spec-level default timezone for this specific window. + If not set, the spec-level timezone (or UTC if that is also not set) is used. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - cron + - duration + type: object + maxItems: 20 + type: array + key: + description: |- + Key is the gate name referenced in the PromotionStrategy's proposedCommitStatuses. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this scheduled commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + timezone: + default: UTC + description: |- + Timezone is the default IANA timezone name used for evaluating cron expressions across all windows. + Individual windows may override this with their own timezone field. + Defaults to UTC. + maxLength: 64 + pattern: ^[a-zA-Z0-9_/+-]*$ + type: string + required: + - environments + - key + - promotionStrategyRef + type: object + x-kubernetes-validations: + - message: each environment must have at least one allow or exclude window, + either per-environment or global + rule: self.environments.all(e, size(e.allow) > 0 || size(e.exclude) + > 0 || size(self.allow) > 0 || size(self.exclude) > 0) + status: + description: status defines the observed state of ScheduledCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment being + tracked. + items: + description: ScheduledEnvironmentStatus defines the observed window + state for a specific environment. + properties: + active: + description: |- + Active holds details of the currently active window driving the phase. + Nil when no specific window is active (e.g. exclusion-only mode with no active exclusion). + properties: + allow: + description: Allow is the cron expression of the allow window, + if applicable. + type: string + exclude: + description: Exclude is the cron expression of the exclusion + window, if applicable. + type: string + transition: + description: |- + Transition is when this window state is expected to change + (e.g. window closing for active, window opening for next). + format: date-time + type: string + type: object + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + next: + description: |- + Next holds details of the next expected window transition. + Used by UIs for countdown timers and by the controller for precise requeuing. + properties: + allow: + description: Allow is the cron expression of the allow window, + if applicable. + type: string + exclude: + description: Exclude is the cron expression of the exclusion + window, if applicable. + type: string + transition: + description: |- + Transition is when this window state is expected to change + (e.g. window closing for active, window opening for next). + format: date-time + type: string + type: object + phase: + description: Phase represents the current phase of the scheduled + gate. + enum: + - pending + - success + type: string + sha: + description: |- + Sha is the proposed commit SHA being tracked for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - branch + - phase + - sha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_scmproviders.yaml b/bundle/manifests/promoter.argoproj.io_scmproviders.yaml new file mode 100644 index 00000000000..7fe900b0696 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_scmproviders.yaml @@ -0,0 +1,264 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: scmproviders.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: ScmProvider + listKind: ScmProviderList + plural: scmproviders + singular: scmprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScmProvider is the Schema for the scmproviders API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#scmprovider + 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: ScmProviderSpec defines the desired state of ScmProvider + properties: + azureDevOps: + description: AzureDevOps required configuration for Azure DevOps as + the SCM provider + properties: + domain: + description: Domain is the Azure DevOps domain, such as "dev.azure.com". + If using the default Azure DevOps domain, leave this field empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to dev.azure.com, leave + the field blank + rule: self != "dev.azure.com" + organization: + description: Organization is the Azure DevOps organization name. + maxLength: 50 + minLength: 1 + pattern: ^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?$ + type: string + required: + - organization + type: object + bitbucketCloud: + description: BitbucketCloud required configuration for Bitbucket Cloud + as the SCM provider + type: object + fake: + description: Fake required configuration for Fake as the SCM provider + properties: + domain: + description: Domain is the domain of the fake SCM provider. This + is used for testing purposes. + maxLength: 253 + minLength: 1 + type: string + type: object + forgejo: + description: Forgejo required configuration for Forgejo as the SCM + provider + properties: + domain: + description: |- + Domain is the Forgejo domain, such as "codeberg.org" or "forgejo.mycompany.com". + There is no default domain since Forgejo is not a service like Gitlab or Github. + maxLength: 253 + minLength: 1 + type: string + required: + - domain + type: object + gitea: + description: Gitea required configuration for Gitea as the SCM provider + properties: + domain: + description: |- + Domain is the Gitea domain, such as "gitea.com" or "gitea.mycompany.com". + There is no default domain since Gitea is self-hosted. + minLength: 1 + type: string + required: + - domain + type: object + github: + description: GitHub required configuration for GitHub as the SCM provider + properties: + appID: + description: AppID is the GitHub App ID. + format: int64 + minimum: 0 + type: integer + domain: + description: |- + Domain is the GitHub domain, such as "github.mycompany.com". If using the default GitHub domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to github.com, leave + the field blank + rule: self != "github.com" + installationID: + description: |- + InstallationID is the GitHub App Installation ID. If you want to use this ScmProvider for multiple + GitHub orgs, do not specify this field. The installation ID will be inferred from the repo owner + when needed. + format: int64 + minimum: 0 + type: integer + required: + - appID + type: object + gitlab: + description: GitLab required configuration for GitLab as the SCM provider + properties: + domain: + description: |- + Domain is the GitLab domain, such as "gitlab.mycompany.com". If using the default GitLab domain, leave this field + empty. + type: string + x-kubernetes-validations: + - message: Instead of setting the domain to gitlab.com, leave + the field blank + rule: self != "gitlab.com" + type: object + secretRef: + description: SecretRef contains the credentials required to auth to + a specific provider + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [github gitlab forgejo gitea bitbucketCloud + azureDevOps fake] must be set + rule: '[has(self.github),has(self.gitlab),has(self.forgejo),has(self.gitea),has(self.bitbucketCloud),has(self.azureDevOps),has(self.fake)].filter(x,x==true).size() + == 1' + status: + description: ScmProviderStatus defines the observed state of ScmProvider + properties: + conditions: + description: Conditions Represents the observations of the current + state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_timedcommitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_timedcommitstatuses.yaml new file mode 100644 index 00000000000..8536b58922f --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_timedcommitstatuses.yaml @@ -0,0 +1,246 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: timedcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: TimedCommitStatus + listKind: TimedCommitStatusList + plural: timedcommitstatuses + singular: timedcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: TimedCommitStatus is the Schema for the timedcommitstatuses API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#timedcommitstatus + 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: spec defines the desired state of TimedCommitStatus + properties: + environments: + items: + description: TimedCommitStatusEnvironments defines the branch/environment + and duration to wait before reporting the gate as success. + properties: + branch: + description: Branch is the name of the branch/environment you + want to gate for the configured duration. + minLength: 1 + type: string + duration: + description: |- + Duration is the time duration to wait before considering the commit status as success. + The duration should be in a format accepted by Go's time.ParseDuration function, e.g., "5m", "1h30m". + type: string + required: + - branch + - duration + type: object + type: array + key: + default: timer + description: |- + Key is the gate name referenced in the PromotionStrategy's activeCommitStatuses or + proposedCommitStatuses. When omitted, the CRD default is timer. Set Key explicitly, even if you use the CRD default. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + promotionStrategyRef: + description: PromotionStrategyRef is a reference to the promotion + strategy that this timed commit status applies to. + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + required: + - environments + - promotionStrategyRef + type: object + status: + description: status defines the observed state of TimedCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: Environments holds the status of each environment being + tracked. + items: + description: TimedCommitStatusEnvironmentsStatus defines the observed + timing status for a specific environment. + properties: + atMostDurationRemaining: + description: |- + AtMostDurationRemaining is the maximum amount of time remaining until the gate is satisfied. + This is calculated at reconciliation time. When the gate is satisfied (phase=success), this will be 0. + type: string + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + commitTime: + description: CommitTime is when the commit was deployed to the + active environment. + format: date-time + type: string + phase: + description: Phase represents the current phase of the timed + gate. + enum: + - pending + - success + type: string + requiredDuration: + description: |- + RequiredDuration is the duration that must elapse before promotion is allowed. + If this is updated in the spec with a pending time. The new duration will be calculated from the original CommitTime. + Allowing you to extend the duration of an already deployed commit, if the time has not yet elapsed. + type: string + sha: + description: |- + Sha is the commit SHA being tracked for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})$ + type: string + required: + - atMostDurationRemaining + - branch + - commitTime + - phase + - requiredDuration + - sha + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bundle/manifests/promoter.argoproj.io_webrequestcommitstatuses.yaml b/bundle/manifests/promoter.argoproj.io_webrequestcommitstatuses.yaml new file mode 100644 index 00000000000..7dcb505dc14 --- /dev/null +++ b/bundle/manifests/promoter.argoproj.io_webrequestcommitstatuses.yaml @@ -0,0 +1,862 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + creationTimestamp: null + name: webrequestcommitstatuses.promoter.argoproj.io +spec: + group: promoter.argoproj.io + names: + kind: WebRequestCommitStatus + listKind: WebRequestCommitStatusList + plural: webrequestcommitstatuses + singular: webrequestcommitstatus + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.key + name: Key + type: string + - jsonPath: .spec.promotionStrategyRef.name + name: PromotionStrategy + type: string + - jsonPath: .spec.reportOn + name: ReportOn + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: WebRequestCommitStatus is the Schema for the webrequestcommitstatuses + API + externalDocs: + description: CRD reference (examples and behavior) + url: https://gitops-promoter.readthedocs.io/en/stable/crd-specs/#webrequestcommitstatus + 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: spec defines the desired state of WebRequestCommitStatus + properties: + descriptionTemplate: + description: |- + DescriptionTemplate is the human-readable commit status description in the SCM provider (GitHub, GitLab, etc.). + Uses Go templates; variable list and Sprig rules match HTTPRequestSpec (spec.httpRequest). Rendered with the latest + data after the most recent HTTP request and trigger evaluation (unlike spec.httpRequest URL/body/headers, which use pre-request data — see HTTPRequestSpec). + How spec.mode.context restricts template data: see ModeSpec. + + Additional template variables (not in HTTPRequestSpec): + - {{ index .TriggerVariables "key" }}: result of trigger.when.variables.expression this reconcile (nil if not configured) + - {{ index .SuccessVariables "key" }}: result of success.when.variables.expression this reconcile (nil if not configured) + + Examples: "External approval for {{ .Branch }}", "{{ .Phase }} - waiting for external approval". + + If not specified, defaults to empty string. + type: string + httpRequest: + description: HTTPRequest configures the outbound HTTP call. See HTTPRequestSpec. + properties: + authentication: + description: |- + Authentication specifies authentication configuration for the HTTP request. + + Supports multiple authentication methods: + - Basic Auth: HTTP Basic Authentication with username/password + - Bearer Token: Bearer token authentication (e.g., API keys, JWTs) + - OAuth2: OAuth2 client credentials flow for obtaining access tokens + - TLS: Mutual TLS (mTLS) with client certificates + - SCM: Reuses credentials from the ScmProvider referenced by the PromotionStrategy (no extra secret needed) + + For Basic, Bearer, OAuth2, and TLS, credentials must be stored in Kubernetes secrets and referenced via secretRef fields. + For SCM, credentials are obtained automatically from the SCM provider; just set scm: {}. + + Examples: + # Basic Auth + authentication: + basic: + secretRef: + name: my-creds + + # Bearer Token + authentication: + bearer: + secretRef: + name: api-token + + # OAuth2 Client Credentials + authentication: + oauth2: + tokenURL: "https://auth.example.com/oauth/token" + secretRef: + name: oauth-creds + + # TLS Client Certificate + authentication: + tls: + secretRef: + name: my-tls-cert + + # SCM Provider Credentials + authentication: + scm: {} + properties: + basic: + description: |- + Basic specifies HTTP Basic Authentication. + Credentials can be provided inline (with secret references) or via secretRef. + properties: + secretRef: + description: |- + SecretRef references a secret containing username and password. + The secret must contain keys "username" and "password". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + bearer: + description: |- + Bearer specifies Bearer token authentication. + Token can be provided inline (with secret reference) or via secretRef. + properties: + secretRef: + description: |- + SecretRef references a secret containing the bearer token. + The secret must contain key "token". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + oauth2: + description: |- + OAuth2 specifies OAuth2 client credentials authentication. + The controller will automatically obtain access tokens from the specified tokenURL. + properties: + scopes: + description: |- + Scopes to request from the OAuth2 provider. + Optional - some providers don't require scopes for client credentials. + Example: ["read:api", "write:api"] + items: + type: string + type: array + secretRef: + description: |- + SecretRef references a secret containing clientID and clientSecret. + The secret must contain keys "clientID" and "clientSecret". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + tokenURL: + description: |- + TokenURL is the OAuth2 token endpoint where access tokens are obtained. + Example: "https://auth.example.com/oauth/token" + type: string + required: + - secretRef + - tokenURL + type: object + scm: + description: |- + Scm specifies authentication using credentials from the SCM provider. + This uses the credentials configured in the ScmProvider referenced by the PromotionStrategy, + applying the appropriate authentication method based on the SCM provider type + (GitHub App, GitLab token, Azure DevOps PAT, etc.). + To use this auth type, just set it to an empty object, i.e. scm: {}. + type: object + tls: + description: |- + TLS specifies TLS client certificate authentication (mutual TLS). + Requires a secret containing the client certificate and private key. + properties: + secretRef: + description: |- + SecretRef references a secret containing TLS certificate and key. + The secret should be of type kubernetes.io/tls or contain keys "tls.crt" and "tls.key", and optionally "ca.crt". + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + type: object + x-kubernetes-validations: + - message: at most one of the fields in [basic bearer oauth2 tls + scm] may be set + rule: '[has(self.basic),has(self.bearer),has(self.oauth2),has(self.tls),has(self.scm)].filter(x,x==true).size() + <= 1' + bodyTemplate: + description: |- + BodyTemplate is the request body to send. + Supports Go templates (see HTTPRequestSpec for available variables). + type: string + headerTemplates: + additionalProperties: + type: string + description: |- + HeaderTemplates are additional HTTP headers to include in the request. + The map key is the header name and the value is the header value (supports Go templates). + See HTTPRequestSpec for available template variables. + type: object + method: + description: |- + Method is the static HTTP method to use. Mutually exclusive with MethodTemplate. + + Deprecated: Use MethodTemplate instead. A literal value such as `methodTemplate: GET` behaves + identically to `method: GET` and avoids needing two separate fields. Existing resources that + set Method continue to work, but new resources should set MethodTemplate. Method may be + removed in a future release. + enum: + - GET + - POST + - PUT + - PATCH + - DELETE + type: string + methodTemplate: + description: |- + MethodTemplate is the HTTP method, rendered as a Go template with the same variables and + Sprig functions as URLTemplate/BodyTemplate/HeaderTemplates. The rendered string is trimmed + of surrounding whitespace and uppercased; the final value must be one of GET/POST/PUT/PATCH/DELETE + or the reconcile returns an error. A literal value such as `methodTemplate: GET` works + identically to a static method; use templating when the method must vary by reconcile + state (e.g. issuing a search GET on one reconcile and a close POST on the next). + Mutually exclusive with Method (deprecated). + type: string + timeout: + default: 30s + description: Timeout is the maximum time to wait for the HTTP + request to complete. + type: string + urlTemplate: + description: |- + URLTemplate is the HTTP endpoint to request. + Supports Go templates (see HTTPRequestSpec for available variables). + type: string + required: + - urlTemplate + type: object + x-kubernetes-validations: + - message: exactly one of method or methodTemplate must be set + rule: (has(self.method) && self.method.size() > 0) != (has(self.methodTemplate) + && self.methodTemplate.size() > 0) + key: + description: |- + Key is the unique identifier for this validation rule. + It is used as the commit status key and in status messages. + This key is matched against PromotionStrategy's proposedCommitStatuses or activeCommitStatuses + to determine which environments this validation applies to. + Must be lowercase alphanumeric with hyphens, 1–63 characters (pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$). + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + mode: + description: Mode selects polling vs trigger and request scope (context). + See ModeSpec. + properties: + context: + default: environments + description: Context is "environments" (default) or "promotionstrategy". + See the ModeSpec type documentation for behavior, template limits, + and success expression rules. + enum: + - environments + - promotionstrategy + type: string + polling: + description: |- + Polling enables interval-based polling mode. + The controller will poll the HTTP endpoint at the specified interval. + properties: + interval: + default: 1m + description: |- + Interval controls how often to retry the HTTP request while in pending state. + When reportOn is "proposed": stops polling after success for a given SHA. + When reportOn is "active": always polls at this interval. + type: string + type: object + trigger: + description: |- + Trigger enables expression-based triggering mode. + The controller will evaluate the expression to determine when to make HTTP requests. + properties: + requeueDuration: + default: 1m + description: RequeueDuration specifies how long to wait before + requeuing to re-evaluate the trigger expression. + type: string + response: + description: Response optionally configures an expression + that extracts data from the HTTP response into ResponseOutput. + properties: + output: + description: |- + Output is evaluated after the HTTP request completes (any status). Response variables are the same as for spec.success.when.expression — see WhenWithOutputSpec.Expression. + The result is stored in status (environments[].responseOutput or promotionStrategyContext.responseOutput) and exposed on the next reconcile as ResponseOutput in trigger expressions and templates. + Must return a map/object. + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + required: + - output + type: object + when: + description: When configures the boolean guard and optional + output expression that control whether the HTTP request + is made. + properties: + expression: + description: |- + Expression is a boolean expr expression that decides whether the HTTP request should be made. + It is evaluated BEFORE each potential HTTP request. When it returns true the request is made; + when false the controller keeps the previous phase and skips the request. + + Available variables: + - Branch (string): the environment branch currently being processed (empty for the shared HTTP request in promotionstrategy context) + - Phase (string): previous reconcile's phase — per-environment in environments context; aggregate of all branches in promotionstrategy context (success only if all succeeded, failure if any failed, pending otherwise) + - PromotionStrategy (PromotionStrategy): the full PromotionStrategy spec and status + - WebRequestCommitStatus (WebRequestCommitStatus): the full WebRequestCommitStatus spec and status (snapshot from the previous reconcile) + - TriggerOutput (map[string]any): custom data from the previous when.output.expression evaluation + - ResponseOutput (map[string]any): response data from the previous HTTP request (if any) + - SuccessOutput (map[string]any): custom data from the previous success.when.output.expression evaluation + - Variables (map[string]any): when spec.variables is set, the map returned by variables.expression this reconcile; omitted otherwise + + Note: PromotionStrategy.Status.Environments is an ordered array representing the promotion sequence. + Use Branch + filter/find to look up environment-specific data: + find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha + + Examples: + # Always trigger (equivalent to polling mode) + - "true" + + # Only trigger when SHA changes from what we last tracked + - "find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha != (TriggerOutput['lastCheckedSha'] ?? '')" + + # Only trigger when a particular commit status is success (e.g. argocd-health) + - "let env = find(PromotionStrategy.Status.Environments, {.Branch == Branch}); any(env.Proposed.CommitStatuses, {.Key == 'argocd-health' && .Phase == 'success'})" + + # Only retry if the previous response indicated we should + - "ResponseOutput == nil || ResponseOutput.status == 'retry'" + type: string + output: + description: |- + Output optionally holds an expression that produces a map of data to persist across reconcile cycles. + The expression runs on every reconcile (whether or not the HTTP request is made). Its result is stored in + status (per-environment under environments[].triggerOutput, or under promotionStrategyContext.triggerOutput when context is promotionstrategy) + and is available in the next reconcile as TriggerOutput in when.expression, when.output.expression, and in templates. + Use it to track state such as attempt counts, last-seen SHAs, or timestamps. + + Delivery semantics caveat: persisted output is read from the controller's informer cache at the start of the next + reconcile. Under cache-propagation lag, controller restarts, or status-write retries, the next reconcile may not + see the most recently persisted output and may re-fire the HTTP request. Treat this as AT-LEAST-ONCE delivery — + counters built on TriggerOutput are eventually-consistent (a stale read can cause a duplicate increment), so use + them for backoff hints, not for hard "fail after N attempts" gates. + + Variables are the same as for Expression (see above). The expression must return a map/object; every key is stored in TriggerOutput. + + Examples: + # Track SHA to detect changes (idempotent: replays produce the same trackedSha for the same input) + - "{ trackedSha: find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha }" + + # Increment attempt counter (eventually-consistent; may briefly under-count under cache lag) + - "{ attemptCount: (TriggerOutput[\"attemptCount\"] ?? 0) + 1 }" + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + variables: + description: |- + Variables optionally holds an expression that runs before Expression and Output.Expression. + It receives the same variables as Expression (see Expression documentation below) and must return a map/object. + The result is injected as top-level binding Variables (map) for Expression and Output.Expression only — use Variables. in those expressions. + The Variables binding is not set when spec.variables is omitted. It is not available to response.output.expression. + The result is also available in Go templates for DescriptionTemplate and UrlTemplate: + - trigger.when.variables result → {{ index .TriggerVariables "key" }} + - success.when.variables result → {{ index .SuccessVariables "key" }} + properties: + expression: + description: Expression is an expr expression that + must return a map/object. + type: string + required: + - expression + type: object + required: + - expression + type: object + required: + - when + type: object + type: object + x-kubernetes-validations: + - message: exactly one of the fields in [polling trigger] must be + set + rule: '[has(self.polling),has(self.trigger)].filter(x,x==true).size() + == 1' + promotionStrategyRef: + description: |- + PromotionStrategyRef references the PromotionStrategy this applies to. + The controller will check commits from ALL environments in the referenced PromotionStrategy + where this WebRequestCommitStatus.Spec.Key matches an entry in either: + - PromotionStrategy.Spec.ProposedCommitStatuses (applies to all environments), OR + - PromotionStrategy.Spec.ActiveCommitStatuses (applies to all environments), OR + - Environment.ProposedCommitStatuses (applies to specific environment), OR + - Environment.ActiveCommitStatuses (applies to specific environment) + properties: + name: + description: Name is the name of the object to refer to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$ + type: string + required: + - name + type: object + reportOn: + default: proposed + description: |- + ReportOn specifies which commit SHA to report the CommitStatus on. + - "proposed": Reports on the proposed hydrated commit SHA (default) + - "active": Reports on the active hydrated commit SHA + + When "proposed": Polls until success, then stops polling for that SHA. + Use "proposed" for checks that need to run just once before a change is promoted, like an approval step. + + When "active": Polls forever, even after success (active state can change). + Use "active" for checks that monitor the change after it's released, for example a metrics monitoring service. + enum: + - proposed + - active + type: string + success: + description: Success defines when the commit status phase is success. + Evaluated every reconcile. See SuccessSpec. + properties: + when: + description: When is evaluated every reconcile. See WhenWithOutputSpec.Expression. + properties: + expression: + description: |- + Expression is a boolean expr expression that decides whether the HTTP request should be made. + It is evaluated BEFORE each potential HTTP request. When it returns true the request is made; + when false the controller keeps the previous phase and skips the request. + + Available variables: + - Branch (string): the environment branch currently being processed (empty for the shared HTTP request in promotionstrategy context) + - Phase (string): previous reconcile's phase — per-environment in environments context; aggregate of all branches in promotionstrategy context (success only if all succeeded, failure if any failed, pending otherwise) + - PromotionStrategy (PromotionStrategy): the full PromotionStrategy spec and status + - WebRequestCommitStatus (WebRequestCommitStatus): the full WebRequestCommitStatus spec and status (snapshot from the previous reconcile) + - TriggerOutput (map[string]any): custom data from the previous when.output.expression evaluation + - ResponseOutput (map[string]any): response data from the previous HTTP request (if any) + - SuccessOutput (map[string]any): custom data from the previous success.when.output.expression evaluation + - Variables (map[string]any): when spec.variables is set, the map returned by variables.expression this reconcile; omitted otherwise + + Note: PromotionStrategy.Status.Environments is an ordered array representing the promotion sequence. + Use Branch + filter/find to look up environment-specific data: + find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha + + Examples: + # Always trigger (equivalent to polling mode) + - "true" + + # Only trigger when SHA changes from what we last tracked + - "find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha != (TriggerOutput['lastCheckedSha'] ?? '')" + + # Only trigger when a particular commit status is success (e.g. argocd-health) + - "let env = find(PromotionStrategy.Status.Environments, {.Branch == Branch}); any(env.Proposed.CommitStatuses, {.Key == 'argocd-health' && .Phase == 'success'})" + + # Only retry if the previous response indicated we should + - "ResponseOutput == nil || ResponseOutput.status == 'retry'" + type: string + output: + description: |- + Output optionally holds an expression that produces a map of data to persist across reconcile cycles. + The expression runs on every reconcile (whether or not the HTTP request is made). Its result is stored in + status (per-environment under environments[].triggerOutput, or under promotionStrategyContext.triggerOutput when context is promotionstrategy) + and is available in the next reconcile as TriggerOutput in when.expression, when.output.expression, and in templates. + Use it to track state such as attempt counts, last-seen SHAs, or timestamps. + + Delivery semantics caveat: persisted output is read from the controller's informer cache at the start of the next + reconcile. Under cache-propagation lag, controller restarts, or status-write retries, the next reconcile may not + see the most recently persisted output and may re-fire the HTTP request. Treat this as AT-LEAST-ONCE delivery — + counters built on TriggerOutput are eventually-consistent (a stale read can cause a duplicate increment), so use + them for backoff hints, not for hard "fail after N attempts" gates. + + Variables are the same as for Expression (see above). The expression must return a map/object; every key is stored in TriggerOutput. + + Examples: + # Track SHA to detect changes (idempotent: replays produce the same trackedSha for the same input) + - "{ trackedSha: find(PromotionStrategy.Status.Environments, {.Branch == Branch}).Proposed.Hydrated.Sha }" + + # Increment attempt counter (eventually-consistent; may briefly under-count under cache lag) + - "{ attemptCount: (TriggerOutput[\"attemptCount\"] ?? 0) + 1 }" + properties: + expression: + description: Expression is an expr expression that must + return a map/object. + type: string + required: + - expression + type: object + variables: + description: |- + Variables optionally holds an expression that runs before Expression and Output.Expression. + It receives the same variables as Expression (see Expression documentation below) and must return a map/object. + The result is injected as top-level binding Variables (map) for Expression and Output.Expression only — use Variables. in those expressions. + The Variables binding is not set when spec.variables is omitted. It is not available to response.output.expression. + The result is also available in Go templates for DescriptionTemplate and UrlTemplate: + - trigger.when.variables result → {{ index .TriggerVariables "key" }} + - success.when.variables result → {{ index .SuccessVariables "key" }} + properties: + expression: + description: Expression is an expr expression that must + return a map/object. + type: string + required: + - expression + type: object + required: + - expression + type: object + required: + - when + type: object + urlTemplate: + description: |- + UrlTemplate is the commit status target URL in the SCM provider. Same Go templates, variables (including .TriggerVariables and .SuccessVariables), timing, and context rules as DescriptionTemplate. + Typical uses: approval UI, dashboard, API, or runbook links. + To include the reported SHA, walk PromotionStrategy.Status.Environments by Branch: + "https://approvals.example.com/{{ range .PromotionStrategy.Status.Environments }}{{ if eq .Branch $.Branch }}{{ .Proposed.Hydrated.Sha }}{{ end }}{{ end }}" + For branch-only links: "https://dashboard.example.com/{{ .Branch }}/status". + + If not specified, defaults to empty string (no URL shown). + type: string + required: + - httpRequest + - key + - mode + - promotionStrategyRef + - success + type: object + status: + description: status defines the observed state of WebRequestCommitStatus + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + environments: + description: |- + Environments holds the status of each environment when context is "environments". + When context is "promotionstrategy", this slice is empty and PromotionStrategyContext is used instead. + items: + description: |- + WebRequestCommitStatusEnvironmentStatus defines the observed status for a specific environment. + + TriggerOutput, ResponseOutput, and SuccessOutput hold JSON maps written by their respective output expressions. + They are surfaced on the next reconcile as TriggerOutput, ResponseOutput, and SuccessOutput in expr and templates (see WhenWithOutputSpec and HTTPRequestSpec). + properties: + branch: + description: Branch is the name of the branch/environment. + minLength: 1 + type: string + lastRequestTime: + description: LastRequestTime is when the last HTTP request was + made. + format: date-time + type: string + lastResponseStatusCode: + description: LastResponseStatusCode is the HTTP status code + from the last request. + type: integer + lastSuccessfulSha: + description: |- + LastSuccessfulSha is the last commit SHA that achieved success status for this environment. + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + phase: + description: |- + Phase represents the current phase of the validation. + This controller sets only "pending" or "success"; it never sets "failure" (failure is allowed by the enum for API consistency). + enum: + - pending + - success + - failure + type: string + reportedSha: + description: |- + ReportedSha is the commit SHA being reported on for this environment. + This is determined by the reportOn field (proposed or active). + Supports both SHA-1 (40 chars) and SHA-256 (64 chars) Git hash formats. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + responseOutput: + description: ResponseOutput is the map from spec.mode.trigger.response.output.expression + when spec.mode.trigger.response is set; otherwise nil. + type: object + x-kubernetes-preserve-unknown-fields: true + successOutput: + description: |- + SuccessOutput is the map from spec.success.when.output.expression (arbitrary JSON keys). + Evaluated every reconcile (whether or not an HTTP request was made). The result is stored here and + exposed on the next reconcile as SuccessOutput in trigger/success expressions and templates. + type: object + x-kubernetes-preserve-unknown-fields: true + triggerOutput: + description: TriggerOutput is the map from spec.mode.trigger.when.output.expression + (arbitrary JSON keys). + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - branch + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + instanceID: + description: |- + InstanceID mirrors metadata.labels[promoter.argoproj.io/instance-id] stamped on each + reconcile attempt by this install's controller, including when Ready=False; omitted + when the resource has no instance-id label (default install). + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$ + type: string + observedGeneration: + description: |- + ObservedGeneration is the .metadata.generation that this status was reconciled from. + Because status is written via Server-Side Apply with ForceOwnership (which has no + optimistic-concurrency check), this field is the canonical way to detect stale + status writes: compare status.observedGeneration with metadata.generation. + format: int64 + type: integer + promotionStrategyContext: + description: |- + PromotionStrategyContext holds the result of the one HTTP run when context is "promotionstrategy". + At most one request is made per WebRequestCommitStatus; phase(s) are reported on each environment's CommitStatus. + properties: + lastRequestTime: + description: LastRequestTime is when the last HTTP request was + made. + format: date-time + type: string + lastResponseStatusCode: + description: LastResponseStatusCode is the HTTP status code from + the last request. + type: integer + lastSuccessfulShas: + description: |- + LastSuccessfulShas tracks the last SHA that achieved success for each branch. + Used with reportOn "proposed" + polling to skip HTTP requests when all environments + have already succeeded for their current SHAs. + items: + description: WebRequestCommitStatusLastSuccessfulShaItem records + the last successful SHA for one branch in promotionstrategy + context status. + properties: + branch: + description: Branch is the environment branch name (merge + key for lastSuccessfulShas list). + minLength: 1 + type: string + lastSuccessfulSha: + description: LastSuccessfulSha is the SHA that last achieved + success for this branch. + maxLength: 64 + pattern: ^([a-f0-9]{40}|[a-f0-9]{64})?$ + type: string + required: + - branch + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + phasePerBranch: + description: |- + PhasePerBranch holds the resolved phase for each applicable branch. + Every applicable branch is always present after reconciliation. + items: + description: WebRequestCommitStatusPhasePerBranchItem is one + branch's resolved phase in promotionstrategy context status. + properties: + branch: + description: Branch is the environment branch name (merge + key for phasePerBranch list). + minLength: 1 + type: string + phase: + description: Phase is "pending", "success", or "failure". + enum: + - pending + - success + - failure + type: string + required: + - branch + - phase + type: object + type: array + x-kubernetes-list-map-keys: + - branch + x-kubernetes-list-type: map + responseOutput: + description: 'ResponseOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.ResponseOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + successOutput: + description: 'SuccessOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.SuccessOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + triggerOutput: + description: 'TriggerOutput: same semantics as WebRequestCommitStatusEnvironmentStatus.TriggerOutput, + one shared map for context=promotionstrategy.' + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index b9d5e0a274d..1fdd0d91563 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -16,6 +16,20 @@ resources: - bases/cluster-analysis-template-crd.yaml - bases/experiment-crd.yaml - bases/rollout-crd.yaml +- bases/promoter.argoproj.io_argocdcommitstatuses.yaml +- bases/promoter.argoproj.io_changetransferpolicies.yaml +- bases/promoter.argoproj.io_clusterscmproviders.yaml +- bases/promoter.argoproj.io_commitstatuses.yaml +- bases/promoter.argoproj.io_controllerconfigurations.yaml +- bases/promoter.argoproj.io_gitcommitstatuses.yaml +- bases/promoter.argoproj.io_gitrepositories.yaml +- bases/promoter.argoproj.io_promotionstrategies.yaml +- bases/promoter.argoproj.io_pullrequests.yaml +- bases/promoter.argoproj.io_revertcommits.yaml +- bases/promoter.argoproj.io_scheduledcommitstatuses.yaml +- bases/promoter.argoproj.io_scmproviders.yaml +- bases/promoter.argoproj.io_timedcommitstatuses.yaml +- bases/promoter.argoproj.io_webrequestcommitstatuses.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: From 1c366731e7c1803e5a11cdd73755ee13fc2e9bb3 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Tue, 25 Aug 2026 16:47:09 -0400 Subject: [PATCH 03/10] fix: run go mod tidy Signed-off-by: Christopher Coco --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 13b959e01ad..dd363d0c428 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/argoproj-labs/argo-rollouts-manager v0.0.9-0.20260505092152-3e07addcb2cb github.com/argoproj-labs/argocd-image-updater v1.3.0 github.com/argoproj-labs/argocd-operator v0.19.0-rc1.0.20260824193734-c354222740c1 + github.com/argoproj-labs/gitops-promoter v0.35.0 github.com/argoproj/argo-cd/gitops-engine v0.7.1-0.20250908182407-97ad5b59a627 github.com/argoproj/argo-cd/v3 v3.5.1 github.com/go-logr/logr v1.4.4 @@ -28,6 +29,7 @@ require ( k8s.io/apiextensions-apiserver v0.36.2 k8s.io/apimachinery v0.36.4 k8s.io/client-go v0.36.4 + k8s.io/kube-aggregator v0.36.1 k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/yaml v1.6.0 @@ -48,7 +50,6 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect - github.com/argoproj-labs/gitops-promoter v0.35.0 // indirect github.com/argoproj/pkg/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -203,7 +204,6 @@ require ( k8s.io/component-helpers v0.36.4 // indirect k8s.io/controller-manager v0.36.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect - k8s.io/kube-aggregator v0.36.1 // indirect k8s.io/kube-openapi v0.0.0-20260706235625-cdb1db5517a0 // indirect k8s.io/kubectl v0.36.1 // indirect k8s.io/kubernetes v1.36.1 // indirect From e62a734382cccc4b24ade5e8f50c2e6fe7b1827c Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Wed, 26 Aug 2026 11:24:33 -0400 Subject: [PATCH 04/10] fix: fix lints and bump other Dockerfiles to 1.26.5 for Go Signed-off-by: Christopher Coco --- openshift-ci/build-root/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openshift-ci/build-root/Dockerfile b/openshift-ci/build-root/Dockerfile index 9bc77e87c17..ad9b02eb705 100644 --- a/openshift-ci/build-root/Dockerfile +++ b/openshift-ci/build-root/Dockerfile @@ -1,6 +1,6 @@ # Dockerfile to bootstrap build and test in openshift-ci -FROM quay.io/devtools_gitops/go-toolset:1.26.3 +FROM quay.io/devtools_gitops/go-toolset:1.26.5 USER root ARG OPERATOR_SDK_VERSION=1.35.0 @@ -23,4 +23,4 @@ RUN curl -sSL -o kustomize.tar.gz https://github.com/kubernetes-sigs/kustomize/r # Install operator-sdk RUN curl -L -o /usr/local/bin/operator-sdk https://github.com/operator-framework/operator-sdk/releases/download/v${OPERATOR_SDK_VERSION}/operator-sdk_linux_amd64 && \ - chmod +x /usr/local/bin/operator-sdk \ No newline at end of file + chmod +x /usr/local/bin/operator-sdk From 97fc39a3b065085bb116cb63316059b99dae95b8 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Thu, 27 Aug 2026 15:43:13 -0400 Subject: [PATCH 05/10] rerun ci Signed-off-by: Christopher Coco From b830d34d9b88675416ecd742cf8ce998c8d224e3 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Thu, 27 Aug 2026 16:09:27 -0400 Subject: [PATCH 06/10] fix: add promoter and apiregistration to e2e test fixture and main Signed-off-by: Christopher Coco --- cmd/main.go | 4 ++++ .../e2e/ginkgo/fixture/utils/fixtureUtils.go | 13 ++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 5c2e52707da..d0979b6406e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -35,6 +35,7 @@ import ( rolloutManagerProvisioner "github.com/argoproj-labs/argo-rollouts-manager/controllers" argov1alpha1api "github.com/argoproj-labs/argocd-operator/api/v1alpha1" argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1" + promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" argocdcommon "github.com/argoproj-labs/argocd-operator/common" argocdprovisioner "github.com/argoproj-labs/argocd-operator/controllers/argocd" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -53,6 +54,7 @@ import ( corev1 "k8s.io/api/core/v1" crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" @@ -273,6 +275,8 @@ func main() { registerComponentOrExit(mgr, argov1alpha1api.AddToScheme) registerComponentOrExit(mgr, argov1beta1api.AddToScheme) + registerComponentOrExit(mgr, promoter.AddToScheme) + registerComponentOrExit(mgr, apiregistrationv1.AddToScheme) // Setup Scheme for OpenShift Config if available // Disables default Argo CD instance if the cluster doesn't contain OpenShift config API diff --git a/test/openshift/e2e/ginkgo/fixture/utils/fixtureUtils.go b/test/openshift/e2e/ginkgo/fixture/utils/fixtureUtils.go index 5cb43cb818e..6708979b714 100644 --- a/test/openshift/e2e/ginkgo/fixture/utils/fixtureUtils.go +++ b/test/openshift/e2e/ginkgo/fixture/utils/fixtureUtils.go @@ -19,6 +19,7 @@ import ( rolloutmanagerv1alpha1 "github.com/argoproj-labs/argo-rollouts-manager/api/v1alpha1" imageUpdater "github.com/argoproj-labs/argocd-image-updater/api/v1alpha1" argov1alpha1api "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" consolev1 "github.com/openshift/api/console/v1" routev1 "github.com/openshift/api/route/v1" securityv1 "github.com/openshift/api/security/v1" @@ -32,6 +33,7 @@ import ( networkingv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" . "github.com/onsi/gomega" ) @@ -62,7 +64,6 @@ func GetE2ETestKubeClientWithError() (client.Client, *runtime.Scheme, error) { // getKubeClient returns a controller-runtime Client for accessing K8s API resources used by the controller. func getKubeClient(config *rest.Config) (client.Client, *runtime.Scheme, error) { - scheme := runtime.NewScheme() if err := corev1.AddToScheme(scheme); err != nil { @@ -151,18 +152,24 @@ func getKubeClient(config *rest.Config) (client.Client, *runtime.Scheme, error) return nil, nil, err } + if err := apiregistrationv1.AddToScheme(scheme); err != nil { + return nil, nil, err + } + + if err := promoter.AddToScheme(scheme); err != nil { + return nil, nil, err + } + k8sClient, err := client.New(config, client.Options{Scheme: scheme}) if err != nil { return nil, nil, err } return k8sClient, scheme, nil - } // Retrieve the system-level Kubernetes config (e.g. ~/.kube/config or service account config from volume) func getSystemKubeConfig() (*rest.Config, error) { - overrides := clientcmd.ConfigOverrides{} loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() From c0e36044042c033eb251ccfac3fbb5a8579f765f Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Thu, 27 Aug 2026 17:09:08 -0400 Subject: [PATCH 07/10] fix: port edited rbac for promoter resources and apiservices Signed-off-by: Christopher Coco --- ...gitops-operator.clusterserviceversion.yaml | 22 ++++++++++++++++++- config/rbac/role.yaml | 20 +++++++++++++++++ controllers/gitopsservice_controller.go | 4 +++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/bundle/manifests/gitops-operator.clusterserviceversion.yaml b/bundle/manifests/gitops-operator.clusterserviceversion.yaml index 49161bf6166..ae96660a042 100644 --- a/bundle/manifests/gitops-operator.clusterserviceversion.yaml +++ b/bundle/manifests/gitops-operator.clusterserviceversion.yaml @@ -190,7 +190,7 @@ metadata: capabilities: Deep Insights console.openshift.io/plugins: '["gitops-plugin"]' containerImage: quay.io/redhat-developer/gitops-operator - createdAt: "2026-08-25T20:41:02Z" + createdAt: "2026-08-27T21:08:40Z" description: Enables teams to adopt GitOps principles for managing cluster configurations and application delivery across hybrid multi-cluster Kubernetes environments. features.operators.openshift.io/disconnected: "true" @@ -516,8 +516,13 @@ spec: resources: - apiservices verbs: + - create + - delete - get - list + - patch + - update + - watch - apiGroups: - appmesh.k8s.aws resources: @@ -828,6 +833,21 @@ spec: - get - patch - update + - apiGroups: + - promoter.argoproj.io + resources: + - '*' + verbs: + - get + - list + - apiGroups: + - promoter.argoproj.io + resources: + - controllerconfigurations + - controllerconfigurations/finalizers + - controllerconfigurations/status + verbs: + - '*' - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 0f22348a5da..045658b3e00 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -71,8 +71,13 @@ rules: resources: - apiservices verbs: + - create + - delete - get - list + - patch + - update + - watch - apiGroups: - appmesh.k8s.aws resources: @@ -383,6 +388,21 @@ rules: - get - patch - update +- apiGroups: + - promoter.argoproj.io + resources: + - '*' + verbs: + - get + - list +- apiGroups: + - promoter.argoproj.io + resources: + - controllerconfigurations + - controllerconfigurations/finalizers + - controllerconfigurations/status + verbs: + - '*' - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/controllers/gitopsservice_controller.go b/controllers/gitopsservice_controller.go index 6c434d93fb0..a5dd57baabf 100644 --- a/controllers/gitopsservice_controller.go +++ b/controllers/gitopsservice_controller.go @@ -221,7 +221,9 @@ type ReconcileGitopsService struct { //+kubebuilder:rbac:groups="x.getambassador.io",resources=ambassadormappings;mappings,verbs=create;watch;get;update;list;delete //+kubebuilder:rbac:groups=argoproj.io,resources=notificationsconfigurations;notificationsconfigurations/finalizers,verbs=* //+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch; -//+kubebuilder:rbac:groups="apiregistration.k8s.io",resources="apiservices",verbs=get;list +//+kubebuilder:rbac:groups="apiregistration.k8s.io",resources="apiservices",verbs=create;delete;get;list;update;patch;watch +//+kubebuilder:rbac:groups=promoter.argoproj.io,resources=controllerconfigurations;controllerconfigurations/status;controllerconfigurations/finalizers,verbs=* +//+kubebuilder:rbac:groups=promoter.argoproj.io,resources=*,verbs=get;list //+kubebuilder:rbac:groups="argoproj.io",resources=namespacemanagements;namespacemanagements/status,verbs=create;get;list;watch;update;patch;delete;deletecollection //+kubebuilder:rbac:groups="config.openshift.io",resources=ingresses,verbs=get;list;watch //+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create From ab425627e65bea3d0df62ffe0fa7c345f443d621 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Fri, 28 Aug 2026 14:44:05 -0400 Subject: [PATCH 08/10] fix: add promoter namespaces to Makefile for e2e tests Signed-off-by: Christopher Coco --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e4558fcbacd..464df997f43 100644 --- a/Makefile +++ b/Makefile @@ -199,7 +199,7 @@ build: generate fmt vet ## Build manager binary. .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - CLUSTER_SCOPED_ARGO_ROLLOUTS_NAMESPACES=argo-rollouts,test-rom-ns-1,rom-ns-1,openshift-gitops ARGOCD_CLUSTER_CONFIG_NAMESPACES="openshift-gitops, argocd-e2e-cluster-config, argocd-test-impersonation-1-046, argocd-agent-principal-1-051, argocd-agent-agent-1-052, appset-argocd, appset-old-ns, appset-new-ns, ns-hosting-principal, ns-hosting-managed-agent, ns-hosting-autonomous-agent, appset-argocd-clusterrole" REDIS_CONFIG_PATH="build/redis" go run ./cmd/main.go + CLUSTER_SCOPED_ARGO_ROLLOUTS_NAMESPACES=argo-rollouts,test-rom-ns-1,rom-ns-1,openshift-gitops ARGOCD_CLUSTER_CONFIG_NAMESPACES="openshift-gitops, argocd-e2e-cluster-config, argocd-test-impersonation-1-046, argocd-agent-principal-1-051, argocd-agent-agent-1-052, appset-argocd, appset-old-ns, appset-new-ns, ns-hosting-principal, ns-hosting-managed-agent, ns-hosting-autonomous-agent, appset-argocd-clusterrole, gitops-promoter-1-134" REDIS_CONFIG_PATH="build/redis" go run ./cmd/main.go .PHONY: docker-build docker-build: test ## Build container image with the manager. From 0f10dbd6af233cf2f2a51d338433016934b78af0 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Fri, 28 Aug 2026 14:55:36 -0400 Subject: [PATCH 09/10] fix: lint Signed-off-by: Christopher Coco --- cmd/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index d0979b6406e..e7e5a4451ab 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -35,13 +35,13 @@ import ( rolloutManagerProvisioner "github.com/argoproj-labs/argo-rollouts-manager/controllers" argov1alpha1api "github.com/argoproj-labs/argocd-operator/api/v1alpha1" argov1beta1api "github.com/argoproj-labs/argocd-operator/api/v1beta1" - promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" argocdcommon "github.com/argoproj-labs/argocd-operator/common" argocdprovisioner "github.com/argoproj-labs/argocd-operator/controllers/argocd" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" notificationsprovisioner "github.com/argoproj-labs/argocd-operator/controllers/notificationsconfiguration" "github.com/argoproj-labs/argocd-operator/pkg/cacheutils" cw "github.com/argoproj-labs/argocd-operator/pkg/clientwrapper" + promoter "github.com/argoproj-labs/gitops-promoter/api/v1alpha1" appsv1 "github.com/openshift/api/apps/v1" configv1 "github.com/openshift/api/config/v1" console "github.com/openshift/api/console/v1" @@ -54,9 +54,9 @@ import ( corev1 "k8s.io/api/core/v1" crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" - apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" crclient "sigs.k8s.io/controller-runtime/pkg/client" From d36fb03fc84f84fa3af635afc972ea4f527c5288 Mon Sep 17 00:00:00 2001 From: Christopher Coco Date: Fri, 28 Aug 2026 16:11:21 -0400 Subject: [PATCH 10/10] fix: add namespace in promoter test Signed-off-by: Christopher Coco --- .../ginkgo/sequential/1-134_validate_gitops_promoter_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go b/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go index 30cdc738f5b..7485cfe844a 100644 --- a/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go +++ b/test/openshift/e2e/ginkgo/sequential/1-134_validate_gitops_promoter_test.go @@ -82,6 +82,10 @@ var _ = Describe("GitOps Operator Sequential E2E Tests", func() { ) BeforeEach(func() { + if !fixture.EnvLocalRun() { + fixture.SetEnvInOperatorSubscriptionOrDeployment("ARGOCD_CLUSTER_CONFIG_NAMESPACES", "openshift-gitops, gitops-promoter-1-134") + } + fixture.EnsureSequentialCleanSlate() k8sClient, _ = fixtureUtils.GetE2ETestKubeClient() ctx = context.Background()