Skip to content

Commit fc888e5

Browse files
authored
Implement API changes according to RFC spec (#1166)
resolves #1088 Summary: * v1 API now uses a `SourceConfig` discriminated union which will allow modularity for future install sources (bundles, charts, etc). * `SourceConfig` uses CEL validation to ensure only valid field names & values are utilized (`sourceType: Catalog` ensures that the `catalog` field is also set in `SourceConfig`). * Added new `clusterextension_admission` unit test for `SourceConfig` objects. The test covers both valid and invalid cases. * Fixed `clusterextension_controller` test where an unset `ClusterExtension` spec caused a null pointer deref. * Moved `ClusterSelector` from `ClusterExtension.Spec` to `ClusterExtension.Source.Catalog` and renamed to `Selector`. * Updated GoDocs to reflect the new API spec and included post-review changes * Fixed all definitions of `kind: ClusterExtension` in docs and scripts to reflect the API changes. Signed-off-by: Josh Manning <19478595+jsm84@users.noreply.github.com>
1 parent bf7f766 commit fc888e5

16 files changed

+796
-403
lines changed

api/v1alpha1/clusterextension_types.go

Lines changed: 93 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,97 @@ const (
4646

4747
// ClusterExtensionSpec defines the desired state of ClusterExtension
4848
type ClusterExtensionSpec struct {
49+
// source is a required field which selects the installation source of content
50+
// for this ClusterExtension. Selection is performed by setting the sourceType.
51+
//
52+
// Catalog is currently the only implemented sourceType, and setting the
53+
// sourcetype to "Catalog" requires the catalog field to also be defined.
54+
//
55+
// Below is a minimal example of a source definition (in yaml):
56+
//
57+
// source:
58+
// sourceType: Catalog
59+
// catalog:
60+
// packageName: example-package
61+
//
62+
Source SourceConfig `json:"source"`
63+
64+
// installNamespace is a reference to the Namespace in which the bundle of
65+
// content for the package referenced in the packageName field will be applied.
66+
// The bundle may contain cluster-scoped resources or resources that are
67+
// applied to other Namespaces. This Namespace is expected to exist.
68+
//
69+
// installNamespace is required, immutable, and follows the DNS label standard
70+
// as defined in RFC 1123. This means that valid values:
71+
// - Contain no more than 63 characters
72+
// - Contain only lowercase alphanumeric characters or '-'
73+
// - Start with an alphanumeric character
74+
// - End with an alphanumeric character
75+
//
76+
// Some examples of valid values are:
77+
// - some-namespace
78+
// - 123-namespace
79+
// - 1-namespace-2
80+
// - somenamespace
81+
//
82+
// Some examples of invalid values are:
83+
// - -some-namespace
84+
// - some-namespace-
85+
// - thisisareallylongnamespacenamethatisgreaterthanthemaximumlength
86+
// - some.namespace
87+
//
88+
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
89+
//+kubebuilder:validation:MaxLength:=63
90+
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="installNamespace is immutable"
91+
InstallNamespace string `json:"installNamespace"`
92+
93+
// preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field.
94+
//
95+
// When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation.
96+
//
97+
// When not specified, the default configuration for each preflight check will be used.
98+
//
99+
//+optional
100+
Preflight *PreflightConfig `json:"preflight,omitempty"`
101+
102+
// serviceAccount is a required reference to a ServiceAccount that exists
103+
// in the installNamespace. The provided ServiceAccount is used to install and
104+
// manage the content for the package specified in the packageName field.
105+
//
106+
// In order to successfully install and manage the content for the package,
107+
// the ServiceAccount provided via this field should be configured with the
108+
// appropriate permissions to perform the necessary operations on all the
109+
// resources that are included in the bundle of content being applied.
110+
ServiceAccount ServiceAccountReference `json:"serviceAccount"`
111+
}
112+
113+
const SourceTypeCatalog = "Catalog"
114+
115+
// SourceConfig is a discriminated union which selects the installation source.
116+
// +union
117+
// +kubebuilder:validation:XValidation:rule="self.sourceType == 'Catalog' && has(self.catalog)",message="sourceType Catalog requires catalog field"
118+
type SourceConfig struct {
119+
// sourceType is a required reference to the type of install source.
120+
//
121+
// Allowed values are ["Catalog"]
122+
//
123+
// When this field is set to "Catalog", information for determining the appropriate
124+
// bundle of content to install will be fetched from ClusterCatalog resources existing
125+
// on the cluster. When using the Catalog sourceType, the catalog field must also be set.
126+
//
127+
// +unionDiscriminator
128+
// +kubebuilder:validation:Enum:="Catalog"
129+
SourceType string `json:"sourceType"`
130+
131+
// catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog",
132+
// and must be the only field defined for this sourceType.
133+
//
134+
// +optional.
135+
Catalog *CatalogSource `json:"catalog,omitempty"`
136+
}
137+
138+
// CatalogSource defines the required fields for catalog source.
139+
type CatalogSource struct {
49140
// packageName is a reference to the name of the package to be installed
50141
// and is used to filter the content from catalogs.
51142
//
@@ -196,15 +287,15 @@ type ClusterExtensionSpec struct {
196287
//+optional
197288
Channel string `json:"channel,omitempty"`
198289

199-
// catalogSelector is an optional field that can be used
290+
// selector is an optional field that can be used
200291
// to filter the set of ClusterCatalogs used in the bundle
201292
// selection process.
202293
//
203294
// When unspecified, all ClusterCatalogs will be used in
204295
// the bundle selection process.
205296
//
206297
//+optional
207-
CatalogSelector metav1.LabelSelector `json:"catalogSelector,omitempty"`
298+
Selector metav1.LabelSelector `json:"selector,omitempty"`
208299

209300
// upgradeConstraintPolicy is an optional field that controls whether
210301
// the upgrade path(s) defined in the catalog are enforced for the package
@@ -228,54 +319,6 @@ type ClusterExtensionSpec struct {
228319
//+kubebuilder:default:=Enforce
229320
//+optional
230321
UpgradeConstraintPolicy UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"`
231-
232-
// installNamespace is a reference to the Namespace in which the bundle of
233-
// content for the package referenced in the packageName field will be applied.
234-
// The bundle may contain cluster-scoped resources or resources that are
235-
// applied to other Namespaces. This Namespace is expected to exist.
236-
//
237-
// installNamespace is required, immutable, and follows the DNS label standard
238-
// as defined in RFC 1123. This means that valid values:
239-
// - Contain no more than 63 characters
240-
// - Contain only lowercase alphanumeric characters or '-'
241-
// - Start with an alphanumeric character
242-
// - End with an alphanumeric character
243-
//
244-
// Some examples of valid values are:
245-
// - some-namespace
246-
// - 123-namespace
247-
// - 1-namespace-2
248-
// - somenamespace
249-
//
250-
// Some examples of invalid values are:
251-
// - -some-namespace
252-
// - some-namespace-
253-
// - thisisareallylongnamespacenamethatisgreaterthanthemaximumlength
254-
// - some.namespace
255-
//
256-
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
257-
//+kubebuilder:validation:MaxLength:=63
258-
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="installNamespace is immutable"
259-
InstallNamespace string `json:"installNamespace"`
260-
261-
// preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field.
262-
//
263-
// When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation.
264-
//
265-
// When not specified, the default configuration for each preflight check will be used.
266-
//
267-
//+optional
268-
Preflight *PreflightConfig `json:"preflight,omitempty"`
269-
270-
// serviceAccount is a required reference to a ServiceAccount that exists
271-
// in the installNamespace. The provided ServiceAccount is used to install and
272-
// manage the content for the package specified in the packageName field.
273-
//
274-
// In order to successfully install and manage the content for the package,
275-
// the ServiceAccount provided via this field should be configured with the
276-
// appropriate permissions to perform the necessary operations on all the
277-
// resources that are included in the bundle of content being applied.
278-
ServiceAccount ServiceAccountReference `json:"serviceAccount"`
279322
}
280323

281324
// ServiceAccountReference references a serviceAccount.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 37 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)