diff --git a/api/v1/clusterextensionrevision_types.go b/api/v1/clusterextensionrevision_types.go index e048e1b54..69a116300 100644 --- a/api/v1/clusterextensionrevision_types.go +++ b/api/v1/clusterextensionrevision_types.go @@ -24,11 +24,15 @@ import ( const ( ClusterExtensionRevisionKind = "ClusterExtensionRevision" - // Condition Types + // ClusterExtensionRevisionTypeAvailable is the condition type that represents whether the + // ClusterExtensionRevision is available and has been successfully rolled out. ClusterExtensionRevisionTypeAvailable = "Available" + + // ClusterExtensionRevisionTypeSucceeded is the condition type that represents whether the + // ClusterExtensionRevision rollout has succeeded. ClusterExtensionRevisionTypeSucceeded = "Succeeded" - // Condition Reasons + // Condition reasons ClusterExtensionRevisionReasonAvailable = "Available" ClusterExtensionRevisionReasonReconcileFailure = "ReconcileFailure" ClusterExtensionRevisionReasonRevisionValidationFailure = "RevisionValidationFailure" @@ -44,22 +48,47 @@ const ( // ClusterExtensionRevisionSpec defines the desired state of ClusterExtensionRevision. type ClusterExtensionRevisionSpec struct { - // Specifies the lifecycle state of the ClusterExtensionRevision. + // lifecycleState specifies the lifecycle state of the ClusterExtensionRevision. + // + // When set to "Active" (the default), the revision is actively managed and reconciled. + // When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted. + // The revision is removed from the owner list of all objects previously under management. + // All objects that did not transition to a succeeding revision are deleted. + // + // Once a revision is set to "Archived", it cannot be un-archived. // // +kubebuilder:default="Active" - // +kubebuilder:validation:Enum=Active;Paused;Archived - // +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Paused' || oldSelf == 'Archived' && oldSelf == self", message="can not un-archive" + // +kubebuilder:validation:Enum=Active;Archived + // +kubebuilder:validation:XValidation:rule="oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == self", message="cannot un-archive" LifecycleState ClusterExtensionRevisionLifecycleState `json:"lifecycleState,omitempty"` - // Revision is a sequence number representing a specific revision of the ClusterExtension instance. - // Must be positive. Each ClusterExtensionRevision of the same parent ClusterExtension needs to have - // a unique value assigned. It is immutable after creation. The new revision number must always be previous revision +1. + + // revision is a required, immutable sequence number representing a specific revision + // of the parent ClusterExtension. + // + // The revision field must be a positive integer. + // Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number. + // The revision number must always be the previous revision number plus one, or 1 for the first revision. // // +kubebuilder:validation:Required // +kubebuilder:validation:Minimum:=1 // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="revision is immutable" Revision int64 `json:"revision"` - // Phases are groups of objects that will be applied at the same time. - // All objects in the phase will have to pass their probes in order to progress to the next phase. + + // phases is an optional, immutable list of phases that group objects to be applied together. + // + // Objects are organized into phases based on their Group-Kind. Common phases include: + // - namespaces: Namespace objects + // - policies: ResourceQuota, LimitRange, NetworkPolicy objects + // - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects + // - crds: CustomResourceDefinition objects + // - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects + // - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects + // - publish: Ingress, APIService, Route, Webhook objects + // + // All objects in a phase are applied in no particular order. + // The revision progresses to the next phase only after all objects in the current phase pass their readiness probes. + // + // Once set, even if empty, the phases field is immutable. // // +kubebuilder:validation:XValidation:rule="self == oldSelf || oldSelf.size() == 0", message="phases is immutable" // +listType=map @@ -75,33 +104,62 @@ const ( // ClusterExtensionRevisionLifecycleStateActive / "Active" is the default lifecycle state. ClusterExtensionRevisionLifecycleStateActive ClusterExtensionRevisionLifecycleState = "Active" // ClusterExtensionRevisionLifecycleStatePaused / "Paused" disables reconciliation of the ClusterExtensionRevision. - // Only Status updates will still propagated, but object changes will not be reconciled. + // Object changes will not be reconciled. However, status updates will be propagated. ClusterExtensionRevisionLifecycleStatePaused ClusterExtensionRevisionLifecycleState = "Paused" - // ClusterExtensionRevisionLifecycleStateArchived / "Archived" disables reconciliation while also "scaling to zero", - // which deletes all objects that are not excluded via the pausedFor property and - // removes itself from the owner list of all other objects previously under management. + // ClusterExtensionRevisionLifecycleStateArchived / "Archived" archives the revision for historical or auditing purposes. + // The revision is removed from the owner list of all other objects previously under management and all objects + // that did not transition to a succeeding revision are deleted. ClusterExtensionRevisionLifecycleStateArchived ClusterExtensionRevisionLifecycleState = "Archived" ) -// ClusterExtensionRevisionPhase are groups of objects that will be applied at the same time. -// All objects in the a phase will have to pass their probes in order to progress to the next phase. +// ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered +// complete only after all objects pass their status probes. type ClusterExtensionRevisionPhase struct { - // Name identifies this phase. + // name is a required identifier for this phase. + // + // phase names must follow the DNS label standard as defined in [RFC 1123]. + // They must contain only lowercase alphanumeric characters or hyphens (-), + // start and end with an alphanumeric character, and be no longer than 63 characters. + // + // Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish. + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 // // +kubebuilder:validation:MaxLength=63 // +kubebuilder:validation:Pattern=`^[a-z]([-a-z0-9]*[a-z0-9])?$` Name string `json:"name"` - // Objects are a list of all the objects within this phase. + + // objects is a required list of all Kubernetes objects that belong to this phase. + // + // All objects in this list are applied to the cluster in no particular order. Objects []ClusterExtensionRevisionObject `json:"objects"` } -// ClusterExtensionRevisionObject contains an object and settings for it. +// ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part +// of a phase, along with its collision protection settings. type ClusterExtensionRevisionObject struct { + // object is a required embedded Kubernetes object to be applied. + // + // This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields. + // // +kubebuilder:validation:EmbeddedResource // +kubebuilder:pruning:PreserveUnknownFields Object unstructured.Unstructured `json:"object"` - // CollisionProtection controls whether OLM can adopt and modify objects - // already existing on the cluster or even owned by another controller. + + // collisionProtection controls whether the operator can adopt and modify objects + // that already exist on the cluster. + // + // When set to "Prevent" (the default), the operator only manages objects it created itself. + // This prevents ownership collisions. + // + // When set to "IfNoController", the operator can adopt and modify pre-existing objects + // that are not owned by another controller. + // This is useful for taking over management of manually-created resources. + // + // When set to "None", the operator can adopt and modify any pre-existing object, even if + // owned by another controller. + // Use this setting with extreme caution as it may cause multiple controllers to fight over + // the same resource, resulting in increased load on the API server and etcd. // // +kubebuilder:default="Prevent" // +kubebuilder:validation:Enum=Prevent;IfNoController;None @@ -128,6 +186,27 @@ const ( // ClusterExtensionRevisionStatus defines the observed state of a ClusterExtensionRevision. type ClusterExtensionRevisionStatus struct { + // conditions is an optional list of status conditions describing the state of the + // ClusterExtensionRevision. + // + // The Progressing condition represents whether the revision is actively rolling out: + // - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition. + // - When Progressing is not present, the revision is not currently in transition. + // + // The Available condition represents whether the revision has been successfully rolled out and is available: + // - When status is True and reason is Available, the revision has been successfully rolled out and all objects pass their readiness probes. + // - When status is False and reason is Incomplete, the revision rollout has not yet completed but no specific failures have been detected. + // - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout. + // - When status is False and reason is ReconcileFailure, the revision has encountered a general reconciliation failure. + // - When status is False and reason is RevisionValidationFailure, the revision failed preflight validation checks. + // - When status is False and reason is PhaseValidationError, a phase within the revision failed preflight validation checks. + // - When status is False and reason is ObjectCollisions, objects in the revision collide with existing cluster objects that cannot be adopted. + // - When status is Unknown and reason is Archived, the revision has been archived and its objects have been torn down. + // - When status is Unknown and reason is Migrated, the revision was migrated from an existing release and object status probe results have not yet been observed. + // + // The Succeeded condition represents whether the revision has successfully completed its rollout: + // - When status is True and reason is RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable. + // // +listType=map // +listMapKey=type // +optional @@ -137,19 +216,24 @@ type ClusterExtensionRevisionStatus struct { // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Cluster // +kubebuilder:subresource:status - -// ClusterExtensionRevision is the Schema for the clusterextensionrevisions API // +kubebuilder:printcolumn:name="Available",type=string,JSONPath=`.status.conditions[?(@.type=='Available')].status` // +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp` + +// ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects +// for a specific version of a ClusterExtension. Each revision contains objects +// organized into phases that roll out sequentially. The same object can only be managed by a single revision +// at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded +// or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for +// posterity. type ClusterExtensionRevision struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - // spec is an optional field that defines the desired state of the ClusterExtension. + // spec defines the desired state of the ClusterExtensionRevision. // +optional Spec ClusterExtensionRevisionSpec `json:"spec,omitempty"` - // status is an optional field that defines the observed state of the ClusterExtension. + // status is optional and defines the observed state of the ClusterExtensionRevision. // +optional Status ClusterExtensionRevisionStatus `json:"status,omitempty"` } diff --git a/commitchecker.yaml b/commitchecker.yaml index 0b1a24c57..0c06b9719 100644 --- a/commitchecker.yaml +++ b/commitchecker.yaml @@ -1,4 +1,4 @@ -expectedMergeBase: 045989d84a7570b1cfddeee47eae64d47245aff2 +expectedMergeBase: 4355cde49b14eb2762f0477b1b213c62db2c023e upstreamBranch: main upstreamOrg: operator-framework upstreamRepo: operator-controller diff --git a/hack/test/install-prometheus.sh b/hack/test/install-prometheus.sh index f458b2d01..e2e13c96f 100755 --- a/hack/test/install-prometheus.sh +++ b/hack/test/install-prometheus.sh @@ -38,8 +38,11 @@ echo "Patching namespace to ${PROMETHEUS_NAMESPACE}..." echo "Applying Prometheus base..." kubectl apply -k "$TMPDIR" --server-side +echo "Waiting for Prometheus Operator deployment to become available..." +kubectl wait --for=condition=Available deployment/prometheus-operator -n "$PROMETHEUS_NAMESPACE" --timeout=180s + echo "Waiting for Prometheus Operator pod to become ready..." -kubectl wait --for=condition=Ready pod -n "$PROMETHEUS_NAMESPACE" -l app.kubernetes.io/name=prometheus-operator +kubectl wait --for=condition=Ready pod -n "$PROMETHEUS_NAMESPACE" -l app.kubernetes.io/name=prometheus-operator --timeout=120s echo "Applying prometheus Helm chart..." ${HELM} template prometheus helm/prometheus ${PROMETHEUS_VALUES} | sed "s/cert-git-version/cert-${VERSION}/g" | kubectl apply -f - diff --git a/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml b/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml index b25e57903..1a3a8b021 100644 --- a/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml +++ b/helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensionrevisions.yaml @@ -25,8 +25,13 @@ spec: name: v1 schema: openAPIV3Schema: - description: ClusterExtensionRevision is the Schema for the clusterextensionrevisions - API + description: |- + ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects + for a specific version of a ClusterExtension. Each revision contains objects + organized into phases that roll out sequentially. The same object can only be managed by a single revision + at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded + or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for + posterity. properties: apiVersion: description: |- @@ -46,53 +51,100 @@ spec: metadata: type: object spec: - description: spec is an optional field that defines the desired state - of the ClusterExtension. + description: spec defines the desired state of the ClusterExtensionRevision. properties: lifecycleState: default: Active - description: Specifies the lifecycle state of the ClusterExtensionRevision. + description: |- + lifecycleState specifies the lifecycle state of the ClusterExtensionRevision. + + When set to "Active" (the default), the revision is actively managed and reconciled. + When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted. + The revision is removed from the owner list of all objects previously under management. + All objects that did not transition to a succeeding revision are deleted. + + Once a revision is set to "Archived", it cannot be un-archived. enum: - Active - - Paused - Archived type: string x-kubernetes-validations: - - message: can not un-archive - rule: oldSelf == 'Active' || oldSelf == 'Paused' || oldSelf == 'Archived' - && oldSelf == self + - message: cannot un-archive + rule: oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == + self phases: description: |- - Phases are groups of objects that will be applied at the same time. - All objects in the phase will have to pass their probes in order to progress to the next phase. + phases is an optional, immutable list of phases that group objects to be applied together. + + Objects are organized into phases based on their Group-Kind. Common phases include: + - namespaces: Namespace objects + - policies: ResourceQuota, LimitRange, NetworkPolicy objects + - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects + - crds: CustomResourceDefinition objects + - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects + - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects + - publish: Ingress, APIService, Route, Webhook objects + + All objects in a phase are applied in no particular order. + The revision progresses to the next phase only after all objects in the current phase pass their readiness probes. + + Once set, even if empty, the phases field is immutable. items: description: |- - ClusterExtensionRevisionPhase are groups of objects that will be applied at the same time. - All objects in the a phase will have to pass their probes in order to progress to the next phase. + ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered + complete only after all objects pass their status probes. properties: name: - description: Name identifies this phase. + description: |- + name is a required identifier for this phase. + + phase names must follow the DNS label standard as defined in [RFC 1123]. + They must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters. + + Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish. + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 maxLength: 63 pattern: ^[a-z]([-a-z0-9]*[a-z0-9])?$ type: string objects: - description: Objects are a list of all the objects within this - phase. + description: |- + objects is a required list of all Kubernetes objects that belong to this phase. + + All objects in this list are applied to the cluster in no particular order. items: - description: ClusterExtensionRevisionObject contains an object - and settings for it. + description: |- + ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part + of a phase, along with its collision protection settings. properties: collisionProtection: default: Prevent description: |- - CollisionProtection controls whether OLM can adopt and modify objects - already existing on the cluster or even owned by another controller. + collisionProtection controls whether the operator can adopt and modify objects + that already exist on the cluster. + + When set to "Prevent" (the default), the operator only manages objects it created itself. + This prevents ownership collisions. + + When set to "IfNoController", the operator can adopt and modify pre-existing objects + that are not owned by another controller. + This is useful for taking over management of manually-created resources. + + When set to "None", the operator can adopt and modify any pre-existing object, even if + owned by another controller. + Use this setting with extreme caution as it may cause multiple controllers to fight over + the same resource, resulting in increased load on the API server and etcd. enum: - Prevent - IfNoController - None type: string object: + description: |- + object is a required embedded Kubernetes object to be applied. + + This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields. type: object x-kubernetes-embedded-resource: true x-kubernetes-preserve-unknown-fields: true @@ -113,9 +165,12 @@ spec: rule: self == oldSelf || oldSelf.size() == 0 revision: description: |- - Revision is a sequence number representing a specific revision of the ClusterExtension instance. - Must be positive. Each ClusterExtensionRevision of the same parent ClusterExtension needs to have - a unique value assigned. It is immutable after creation. The new revision number must always be previous revision +1. + revision is a required, immutable sequence number representing a specific revision + of the parent ClusterExtension. + + The revision field must be a positive integer. + Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number. + The revision number must always be the previous revision number plus one, or 1 for the first revision. format: int64 minimum: 1 type: integer @@ -126,10 +181,31 @@ spec: - revision type: object status: - description: status is an optional field that defines the observed state - of the ClusterExtension. + description: status is optional and defines the observed state of the + ClusterExtensionRevision. properties: conditions: + description: |- + conditions is an optional list of status conditions describing the state of the + ClusterExtensionRevision. + + The Progressing condition represents whether the revision is actively rolling out: + - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition. + - When Progressing is not present, the revision is not currently in transition. + + The Available condition represents whether the revision has been successfully rolled out and is available: + - When status is True and reason is Available, the revision has been successfully rolled out and all objects pass their readiness probes. + - When status is False and reason is Incomplete, the revision rollout has not yet completed but no specific failures have been detected. + - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout. + - When status is False and reason is ReconcileFailure, the revision has encountered a general reconciliation failure. + - When status is False and reason is RevisionValidationFailure, the revision failed preflight validation checks. + - When status is False and reason is PhaseValidationError, a phase within the revision failed preflight validation checks. + - When status is False and reason is ObjectCollisions, objects in the revision collide with existing cluster objects that cannot be adopted. + - When status is Unknown and reason is Archived, the revision has been archived and its objects have been torn down. + - When status is Unknown and reason is Migrated, the revision was migrated from an existing release and object status probe results have not yet been observed. + + The Succeeded condition represents whether the revision has successfully completed its rollout: + - When status is True and reason is RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable. items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/helm/olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml b/helm/olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml new file mode 100644 index 000000000..7e6ec2e33 --- /dev/null +++ b/helm/olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml @@ -0,0 +1,22 @@ +{{- if and .Values.options.catalogd.enabled .Values.options.catalogd.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: {{ .Values.namespaces.olmv1.name }} + labels: + app.kubernetes.io/name: catalogd + {{- include "olmv1.labels" . | nindent 4 }} + annotations: + {{- include "olmv1.annotations" . | nindent 4 }} +spec: + {{- if .Values.options.catalogd.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.options.catalogd.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.options.catalogd.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.options.catalogd.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + control-plane: catalogd-controller-manager +{{- end }} diff --git a/helm/olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml b/helm/olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml new file mode 100644 index 000000000..0d98d528f --- /dev/null +++ b/helm/olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml @@ -0,0 +1,22 @@ +{{- if and .Values.options.operatorController.enabled .Values.options.operatorController.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: {{ .Values.namespaces.olmv1.name }} + labels: + app.kubernetes.io/name: operator-controller + {{- include "olmv1.labels" . | nindent 4 }} + annotations: + {{- include "olmv1.annotations" . | nindent 4 }} +spec: + {{- if .Values.options.operatorController.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.options.operatorController.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.options.operatorController.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.options.operatorController.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + control-plane: operator-controller-controller-manager +{{- end }} diff --git a/helm/olmv1/values.yaml b/helm/olmv1/values.yaml index 5ab9d7672..cb454f625 100644 --- a/helm/olmv1/values.yaml +++ b/helm/olmv1/values.yaml @@ -12,6 +12,9 @@ options: features: enabled: [] disabled: [] + podDisruptionBudget: + enabled: true + minAvailable: 1 catalogd: enabled: true deployment: @@ -20,6 +23,9 @@ options: features: enabled: [] disabled: [] + podDisruptionBudget: + enabled: true + minAvailable: 1 certManager: enabled: false e2e: diff --git a/manifests/experimental-e2e.yaml b/manifests/experimental-e2e.yaml index 672830225..e536cd72a 100644 --- a/manifests/experimental-e2e.yaml +++ b/manifests/experimental-e2e.yaml @@ -87,6 +87,40 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental-e2e +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental-e2e +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount @@ -616,8 +650,13 @@ spec: name: v1 schema: openAPIV3Schema: - description: ClusterExtensionRevision is the Schema for the clusterextensionrevisions - API + description: |- + ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects + for a specific version of a ClusterExtension. Each revision contains objects + organized into phases that roll out sequentially. The same object can only be managed by a single revision + at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded + or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for + posterity. properties: apiVersion: description: |- @@ -637,53 +676,100 @@ spec: metadata: type: object spec: - description: spec is an optional field that defines the desired state - of the ClusterExtension. + description: spec defines the desired state of the ClusterExtensionRevision. properties: lifecycleState: default: Active - description: Specifies the lifecycle state of the ClusterExtensionRevision. + description: |- + lifecycleState specifies the lifecycle state of the ClusterExtensionRevision. + + When set to "Active" (the default), the revision is actively managed and reconciled. + When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted. + The revision is removed from the owner list of all objects previously under management. + All objects that did not transition to a succeeding revision are deleted. + + Once a revision is set to "Archived", it cannot be un-archived. enum: - Active - - Paused - Archived type: string x-kubernetes-validations: - - message: can not un-archive - rule: oldSelf == 'Active' || oldSelf == 'Paused' || oldSelf == 'Archived' - && oldSelf == self + - message: cannot un-archive + rule: oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == + self phases: description: |- - Phases are groups of objects that will be applied at the same time. - All objects in the phase will have to pass their probes in order to progress to the next phase. + phases is an optional, immutable list of phases that group objects to be applied together. + + Objects are organized into phases based on their Group-Kind. Common phases include: + - namespaces: Namespace objects + - policies: ResourceQuota, LimitRange, NetworkPolicy objects + - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects + - crds: CustomResourceDefinition objects + - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects + - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects + - publish: Ingress, APIService, Route, Webhook objects + + All objects in a phase are applied in no particular order. + The revision progresses to the next phase only after all objects in the current phase pass their readiness probes. + + Once set, even if empty, the phases field is immutable. items: description: |- - ClusterExtensionRevisionPhase are groups of objects that will be applied at the same time. - All objects in the a phase will have to pass their probes in order to progress to the next phase. + ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered + complete only after all objects pass their status probes. properties: name: - description: Name identifies this phase. + description: |- + name is a required identifier for this phase. + + phase names must follow the DNS label standard as defined in [RFC 1123]. + They must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters. + + Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish. + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 maxLength: 63 pattern: ^[a-z]([-a-z0-9]*[a-z0-9])?$ type: string objects: - description: Objects are a list of all the objects within this - phase. + description: |- + objects is a required list of all Kubernetes objects that belong to this phase. + + All objects in this list are applied to the cluster in no particular order. items: - description: ClusterExtensionRevisionObject contains an object - and settings for it. + description: |- + ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part + of a phase, along with its collision protection settings. properties: collisionProtection: default: Prevent description: |- - CollisionProtection controls whether OLM can adopt and modify objects - already existing on the cluster or even owned by another controller. + collisionProtection controls whether the operator can adopt and modify objects + that already exist on the cluster. + + When set to "Prevent" (the default), the operator only manages objects it created itself. + This prevents ownership collisions. + + When set to "IfNoController", the operator can adopt and modify pre-existing objects + that are not owned by another controller. + This is useful for taking over management of manually-created resources. + + When set to "None", the operator can adopt and modify any pre-existing object, even if + owned by another controller. + Use this setting with extreme caution as it may cause multiple controllers to fight over + the same resource, resulting in increased load on the API server and etcd. enum: - Prevent - IfNoController - None type: string object: + description: |- + object is a required embedded Kubernetes object to be applied. + + This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields. type: object x-kubernetes-embedded-resource: true x-kubernetes-preserve-unknown-fields: true @@ -704,9 +790,12 @@ spec: rule: self == oldSelf || oldSelf.size() == 0 revision: description: |- - Revision is a sequence number representing a specific revision of the ClusterExtension instance. - Must be positive. Each ClusterExtensionRevision of the same parent ClusterExtension needs to have - a unique value assigned. It is immutable after creation. The new revision number must always be previous revision +1. + revision is a required, immutable sequence number representing a specific revision + of the parent ClusterExtension. + + The revision field must be a positive integer. + Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number. + The revision number must always be the previous revision number plus one, or 1 for the first revision. format: int64 minimum: 1 type: integer @@ -717,10 +806,31 @@ spec: - revision type: object status: - description: status is an optional field that defines the observed state - of the ClusterExtension. + description: status is optional and defines the observed state of the + ClusterExtensionRevision. properties: conditions: + description: |- + conditions is an optional list of status conditions describing the state of the + ClusterExtensionRevision. + + The Progressing condition represents whether the revision is actively rolling out: + - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition. + - When Progressing is not present, the revision is not currently in transition. + + The Available condition represents whether the revision has been successfully rolled out and is available: + - When status is True and reason is Available, the revision has been successfully rolled out and all objects pass their readiness probes. + - When status is False and reason is Incomplete, the revision rollout has not yet completed but no specific failures have been detected. + - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout. + - When status is False and reason is ReconcileFailure, the revision has encountered a general reconciliation failure. + - When status is False and reason is RevisionValidationFailure, the revision failed preflight validation checks. + - When status is False and reason is PhaseValidationError, a phase within the revision failed preflight validation checks. + - When status is False and reason is ObjectCollisions, objects in the revision collide with existing cluster objects that cannot be adopted. + - When status is Unknown and reason is Archived, the revision has been archived and its objects have been torn down. + - When status is Unknown and reason is Migrated, the revision was migrated from an existing release and object status probe results have not yet been observed. + + The Succeeded condition represents whether the revision has successfully completed its rollout: + - When status is True and reason is RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable. items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/manifests/experimental.yaml b/manifests/experimental.yaml index 199838eac..f88debab0 100644 --- a/manifests/experimental.yaml +++ b/manifests/experimental.yaml @@ -87,6 +87,40 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount @@ -581,8 +615,13 @@ spec: name: v1 schema: openAPIV3Schema: - description: ClusterExtensionRevision is the Schema for the clusterextensionrevisions - API + description: |- + ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects + for a specific version of a ClusterExtension. Each revision contains objects + organized into phases that roll out sequentially. The same object can only be managed by a single revision + at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded + or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for + posterity. properties: apiVersion: description: |- @@ -602,53 +641,100 @@ spec: metadata: type: object spec: - description: spec is an optional field that defines the desired state - of the ClusterExtension. + description: spec defines the desired state of the ClusterExtensionRevision. properties: lifecycleState: default: Active - description: Specifies the lifecycle state of the ClusterExtensionRevision. + description: |- + lifecycleState specifies the lifecycle state of the ClusterExtensionRevision. + + When set to "Active" (the default), the revision is actively managed and reconciled. + When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted. + The revision is removed from the owner list of all objects previously under management. + All objects that did not transition to a succeeding revision are deleted. + + Once a revision is set to "Archived", it cannot be un-archived. enum: - Active - - Paused - Archived type: string x-kubernetes-validations: - - message: can not un-archive - rule: oldSelf == 'Active' || oldSelf == 'Paused' || oldSelf == 'Archived' - && oldSelf == self + - message: cannot un-archive + rule: oldSelf == 'Active' || oldSelf == 'Archived' && oldSelf == + self phases: description: |- - Phases are groups of objects that will be applied at the same time. - All objects in the phase will have to pass their probes in order to progress to the next phase. + phases is an optional, immutable list of phases that group objects to be applied together. + + Objects are organized into phases based on their Group-Kind. Common phases include: + - namespaces: Namespace objects + - policies: ResourceQuota, LimitRange, NetworkPolicy objects + - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects + - crds: CustomResourceDefinition objects + - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects + - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects + - publish: Ingress, APIService, Route, Webhook objects + + All objects in a phase are applied in no particular order. + The revision progresses to the next phase only after all objects in the current phase pass their readiness probes. + + Once set, even if empty, the phases field is immutable. items: description: |- - ClusterExtensionRevisionPhase are groups of objects that will be applied at the same time. - All objects in the a phase will have to pass their probes in order to progress to the next phase. + ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered + complete only after all objects pass their status probes. properties: name: - description: Name identifies this phase. + description: |- + name is a required identifier for this phase. + + phase names must follow the DNS label standard as defined in [RFC 1123]. + They must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters. + + Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish. + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 maxLength: 63 pattern: ^[a-z]([-a-z0-9]*[a-z0-9])?$ type: string objects: - description: Objects are a list of all the objects within this - phase. + description: |- + objects is a required list of all Kubernetes objects that belong to this phase. + + All objects in this list are applied to the cluster in no particular order. items: - description: ClusterExtensionRevisionObject contains an object - and settings for it. + description: |- + ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part + of a phase, along with its collision protection settings. properties: collisionProtection: default: Prevent description: |- - CollisionProtection controls whether OLM can adopt and modify objects - already existing on the cluster or even owned by another controller. + collisionProtection controls whether the operator can adopt and modify objects + that already exist on the cluster. + + When set to "Prevent" (the default), the operator only manages objects it created itself. + This prevents ownership collisions. + + When set to "IfNoController", the operator can adopt and modify pre-existing objects + that are not owned by another controller. + This is useful for taking over management of manually-created resources. + + When set to "None", the operator can adopt and modify any pre-existing object, even if + owned by another controller. + Use this setting with extreme caution as it may cause multiple controllers to fight over + the same resource, resulting in increased load on the API server and etcd. enum: - Prevent - IfNoController - None type: string object: + description: |- + object is a required embedded Kubernetes object to be applied. + + This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields. type: object x-kubernetes-embedded-resource: true x-kubernetes-preserve-unknown-fields: true @@ -669,9 +755,12 @@ spec: rule: self == oldSelf || oldSelf.size() == 0 revision: description: |- - Revision is a sequence number representing a specific revision of the ClusterExtension instance. - Must be positive. Each ClusterExtensionRevision of the same parent ClusterExtension needs to have - a unique value assigned. It is immutable after creation. The new revision number must always be previous revision +1. + revision is a required, immutable sequence number representing a specific revision + of the parent ClusterExtension. + + The revision field must be a positive integer. + Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number. + The revision number must always be the previous revision number plus one, or 1 for the first revision. format: int64 minimum: 1 type: integer @@ -682,10 +771,31 @@ spec: - revision type: object status: - description: status is an optional field that defines the observed state - of the ClusterExtension. + description: status is optional and defines the observed state of the + ClusterExtensionRevision. properties: conditions: + description: |- + conditions is an optional list of status conditions describing the state of the + ClusterExtensionRevision. + + The Progressing condition represents whether the revision is actively rolling out: + - When status is True and reason is Progressing, the revision rollout is actively making progress and is in transition. + - When Progressing is not present, the revision is not currently in transition. + + The Available condition represents whether the revision has been successfully rolled out and is available: + - When status is True and reason is Available, the revision has been successfully rolled out and all objects pass their readiness probes. + - When status is False and reason is Incomplete, the revision rollout has not yet completed but no specific failures have been detected. + - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout. + - When status is False and reason is ReconcileFailure, the revision has encountered a general reconciliation failure. + - When status is False and reason is RevisionValidationFailure, the revision failed preflight validation checks. + - When status is False and reason is PhaseValidationError, a phase within the revision failed preflight validation checks. + - When status is False and reason is ObjectCollisions, objects in the revision collide with existing cluster objects that cannot be adopted. + - When status is Unknown and reason is Archived, the revision has been archived and its objects have been torn down. + - When status is Unknown and reason is Migrated, the revision was migrated from an existing release and object status probe results have not yet been observed. + + The Succeeded condition represents whether the revision has successfully completed its rollout: + - When status is True and reason is RolloutSuccess, the revision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable. items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/manifests/standard-e2e.yaml b/manifests/standard-e2e.yaml index 5c9590784..1aed38ba9 100644 --- a/manifests/standard-e2e.yaml +++ b/manifests/standard-e2e.yaml @@ -87,6 +87,40 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard-e2e +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard-e2e +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount diff --git a/manifests/standard.yaml b/manifests/standard.yaml index 95e400c26..34cc57918 100644 --- a/manifests/standard.yaml +++ b/manifests/standard.yaml @@ -87,6 +87,40 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: olmv1-system + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount diff --git a/openshift/catalogd/manifests-experimental.yaml b/openshift/catalogd/manifests-experimental.yaml index 4dacdee86..06bd2abd8 100644 --- a/openshift/catalogd/manifests-experimental.yaml +++ b/openshift/catalogd/manifests-experimental.yaml @@ -65,6 +65,23 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: openshift-catalogd + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount diff --git a/openshift/catalogd/manifests.yaml b/openshift/catalogd/manifests.yaml index 68b6c87f3..e197256bf 100644 --- a/openshift/catalogd/manifests.yaml +++ b/openshift/catalogd/manifests.yaml @@ -65,6 +65,23 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-catalogd.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: catalogd-controller-manager + namespace: openshift-catalogd + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount diff --git a/openshift/operator-controller/manifests-experimental.yaml b/openshift/operator-controller/manifests-experimental.yaml index 6ecb52ff2..e8893063e 100644 --- a/openshift/operator-controller/manifests-experimental.yaml +++ b/openshift/operator-controller/manifests-experimental.yaml @@ -61,6 +61,23 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: openshift-operator-controller + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: experimental +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount diff --git a/openshift/operator-controller/manifests.yaml b/openshift/operator-controller/manifests.yaml index 091dfe26a..8d2be5ecf 100644 --- a/openshift/operator-controller/manifests.yaml +++ b/openshift/operator-controller/manifests.yaml @@ -61,6 +61,23 @@ spec: - Ingress - Egress --- +# Source: olmv1/templates/poddisruptionbudget-olmv1-system-operator-controller.yml +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: operator-controller-controller-manager + namespace: openshift-operator-controller + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + annotations: + olm.operatorframework.io/feature-set: standard +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager +--- # Source: olmv1/templates/serviceaccount-olmv1-system-common-controller-manager.yml apiVersion: v1 kind: ServiceAccount