Skip to content

Commit 662ecf2

Browse files
perdasilvaPer G. da Silva
andauthored
Refine registry+v1 revision phase definitions for granular resource ordering (#2520)
Restructure the phase definitions to provide more granular control over the order in which Kubernetes resources are applied during extension installation. The previous coarse-grained phases (rbac, deploy, publish) are replaced with finer-grained phases that better reflect resource dependency chains and operational best practices. Phase changes: - Split "rbac" into "identity" (ServiceAccount), "roles" (ClusterRole, Role), and "bindings" (ClusterRoleBinding, RoleBinding) for explicit ordering of RBAC prerequisites before their bindings - Extract "configuration" phase (Secret, ConfigMap) from "deploy" so config resources are available before workloads that mount them - Extract "infrastructure" phase (Service, Issuer) from "deploy" so services and cert-manager issuers exist before workloads reference them - Add "scaling" phase (VerticalPodAutoscaler) after deploy for autoscaling policies to target running workloads - Add "admission" phase (ValidatingWebhookConfiguration, MutatingWebhookConfiguration) as the final phase so webhooks are registered only after their backing services are ready - Move CRDs before roles/bindings so RBAC rules referencing custom resources can be validated - Add cert-manager Certificate to "deploy" phase alongside Deployment - Add monitoring resources (PrometheusRule, ServiceMonitor, PodMonitor) and OpenShift console resources to "publish" phase - Remove explicit mappings for workload kinds that already default to "deploy" (DaemonSet, StatefulSet, ReplicaSet, Pod, Job, CronJob) New phase order: namespaces → policies → identity → configuration → storage → crds → roles → bindings → infrastructure → deploy → scaling → publish → admission Signed-off-by: Per G. da Silva <pegoncal@redhat.com> Co-authored-by: Per G. da Silva <pegoncal@redhat.com>
1 parent b49a5b8 commit 662ecf2

File tree

3 files changed

+221
-91
lines changed

3 files changed

+221
-91
lines changed

internal/operator-controller/applier/boxcutter_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func Test_SimpleRevisionGenerator_GenerateRevisionFromHelmRelease(t *testing.T)
119119
Revision: 1,
120120
Phases: []ocv1.ClusterExtensionRevisionPhase{
121121
{
122-
Name: "deploy",
122+
Name: "configuration",
123123
Objects: []ocv1.ClusterExtensionRevisionObject{
124124
{
125125
Object: unstructured.Unstructured{
@@ -219,7 +219,7 @@ func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) {
219219
t.Log("by checking the rendered objects are present in the correct phases")
220220
require.Equal(t, []ocv1.ClusterExtensionRevisionPhase{
221221
{
222-
Name: string(applier.PhaseDeploy),
222+
Name: string(applier.PhaseInfrastructure),
223223
Objects: []ocv1.ClusterExtensionRevisionObject{
224224
{
225225
Object: unstructured.Unstructured{
@@ -233,6 +233,11 @@ func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) {
233233
},
234234
},
235235
},
236+
},
237+
},
238+
{
239+
Name: string(applier.PhaseDeploy),
240+
Objects: []ocv1.ClusterExtensionRevisionObject{
236241
{
237242
Object: unstructured.Unstructured{
238243
Object: map[string]interface{}{

internal/operator-controller/applier/phase.go

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,44 @@ func determinePhase(gk schema.GroupKind) Phase {
2828
type Phase string
2929

3030
const (
31-
PhaseNamespaces Phase = "namespaces"
32-
PhasePolicies Phase = "policies"
33-
PhaseRBAC Phase = "rbac"
34-
PhaseRBACBindings Phase = "rbac-bindings"
35-
PhaseCRDs Phase = "crds"
36-
PhaseStorage Phase = "storage"
37-
PhaseDeploy Phase = "deploy"
38-
PhasePublish Phase = "publish"
31+
PhaseNamespaces Phase = "namespaces"
32+
PhasePolicies Phase = "policies"
33+
PhaseIdentity Phase = "identity"
34+
PhaseConfiguration Phase = "configuration"
35+
PhaseStorage Phase = "storage"
36+
PhaseCRDs Phase = "crds"
37+
PhaseRoles Phase = "roles"
38+
PhaseBindings Phase = "bindings"
39+
PhaseInfrastructure Phase = "infrastructure"
40+
PhaseDeploy Phase = "deploy"
41+
PhaseScaling Phase = "scaling"
42+
PhasePublish Phase = "publish"
43+
PhaseAdmission Phase = "admission"
3944
)
4045

4146
// Well known phases ordered.
4247
var defaultPhaseOrder = []Phase{
4348
PhaseNamespaces,
4449
PhasePolicies,
45-
PhaseRBAC,
46-
PhaseRBACBindings,
47-
PhaseCRDs,
50+
PhaseIdentity,
51+
PhaseConfiguration,
4852
PhaseStorage,
53+
PhaseCRDs,
54+
PhaseRoles,
55+
PhaseBindings,
56+
PhaseInfrastructure,
4957
PhaseDeploy,
58+
PhaseScaling,
5059
PhasePublish,
60+
PhaseAdmission,
5161
}
5262

63+
// Note: OLMv1 currently only supports registry+v1 content. The registry+v1 format only supports a limited
64+
// set of object kinds defined in:
65+
// https://github.com/operator-framework/operator-registry/blob/f410a396abe01dbe6a46b6d90d34bdd844306388/pkg/lib/bundle/supported_resources.go
66+
// The phase mapping considers all allowable registry+v1 bundle format resource with the following changes:
67+
// - ClusterServiceVersion is replaced by the resources it describes: Deployment, Cluster/Role/Binding, ServiceAccount, ValidatingWebhookConfiguration, etc.
68+
// - Certificate and Issuer from cert-manager are added since OLMv1 uses cert-manager for webhook service certificate by default
5369
var (
5470
// This will be populated from `phaseGKMap` in an init func!
5571
gkPhaseMap = map[schema.GroupKind]Phase{}
@@ -59,27 +75,18 @@ var (
5975
},
6076

6177
PhasePolicies: {
62-
{Kind: "ResourceQuota"},
63-
{Kind: "LimitRange"},
64-
{Kind: "PriorityClass", Group: "scheduling.k8s.io"},
6578
{Kind: "NetworkPolicy", Group: "networking.k8s.io"},
66-
{Kind: "HorizontalPodAutoscaler", Group: "autoscaling"},
6779
{Kind: "PodDisruptionBudget", Group: "policy"},
80+
{Kind: "PriorityClass", Group: "scheduling.k8s.io"},
6881
},
6982

70-
PhaseRBAC: {
83+
PhaseIdentity: {
7184
{Kind: "ServiceAccount"},
72-
{Kind: "Role", Group: "rbac.authorization.k8s.io"},
73-
{Kind: "ClusterRole", Group: "rbac.authorization.k8s.io"},
74-
},
75-
76-
PhaseRBACBindings: {
77-
{Kind: "RoleBinding", Group: "rbac.authorization.k8s.io"},
78-
{Kind: "ClusterRoleBinding", Group: "rbac.authorization.k8s.io"},
7985
},
8086

81-
PhaseCRDs: {
82-
{Kind: "CustomResourceDefinition", Group: "apiextensions.k8s.io"},
87+
PhaseConfiguration: {
88+
{Kind: "Secret"},
89+
{Kind: "ConfigMap"},
8390
},
8491

8592
PhaseStorage: {
@@ -88,25 +95,50 @@ var (
8895
{Kind: "StorageClass", Group: "storage.k8s.io"},
8996
},
9097

98+
PhaseCRDs: {
99+
{Kind: "CustomResourceDefinition", Group: "apiextensions.k8s.io"},
100+
},
101+
102+
PhaseRoles: {
103+
{Kind: "ClusterRole", Group: "rbac.authorization.k8s.io"},
104+
{Kind: "Role", Group: "rbac.authorization.k8s.io"},
105+
},
106+
107+
PhaseBindings: {
108+
{Kind: "ClusterRoleBinding", Group: "rbac.authorization.k8s.io"},
109+
{Kind: "RoleBinding", Group: "rbac.authorization.k8s.io"},
110+
},
111+
112+
PhaseInfrastructure: {
113+
{Kind: "Service"},
114+
{Kind: "Issuer", Group: "cert-manager.io"},
115+
},
116+
91117
PhaseDeploy: {
118+
{Kind: "Certificate", Group: "cert-manager.io"},
92119
{Kind: "Deployment", Group: "apps"},
93-
{Kind: "DaemonSet", Group: "apps"},
94-
{Kind: "StatefulSet", Group: "apps"},
95-
{Kind: "ReplicaSet"},
96-
{Kind: "Pod"}, // probing complicated, may be either Completed or Available.
97-
{Kind: "Job", Group: "batch"},
98-
{Kind: "CronJob", Group: "batch"},
99-
{Kind: "Service"},
100-
{Kind: "Secret"},
101-
{Kind: "ConfigMap"},
120+
},
121+
122+
PhaseScaling: {
123+
{Kind: "VerticalPodAutoscaler", Group: "autoscaling.k8s.io"},
102124
},
103125

104126
PhasePublish: {
127+
{Kind: "PrometheusRule", Group: "monitoring.coreos.com"},
128+
{Kind: "ServiceMonitor", Group: "monitoring.coreos.com"},
129+
{Kind: "PodMonitor", Group: "monitoring.coreos.com"},
105130
{Kind: "Ingress", Group: "networking.k8s.io"},
106-
{Kind: "APIService", Group: "apiregistration.k8s.io"},
107131
{Kind: "Route", Group: "route.openshift.io"},
108-
{Kind: "MutatingWebhookConfiguration", Group: "admissionregistration.k8s.io"},
132+
{Kind: "ConsoleYAMLSample", Group: "console.openshift.io"},
133+
{Kind: "ConsoleQuickStart", Group: "console.openshift.io"},
134+
{Kind: "ConsoleCLIDownload", Group: "console.openshift.io"},
135+
{Kind: "ConsoleLink", Group: "console.openshift.io"},
136+
{Kind: "ConsolePlugin", Group: "console.openshift.io"},
137+
},
138+
139+
PhaseAdmission: {
109140
{Kind: "ValidatingWebhookConfiguration", Group: "admissionregistration.k8s.io"},
141+
{Kind: "MutatingWebhookConfiguration", Group: "admissionregistration.k8s.io"},
110142
},
111143
}
112144
)

0 commit comments

Comments
 (0)