Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 75 additions & 51 deletions api/v1alpha1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,53 @@ type ClusterExtensionSpec struct {
//
Source SourceConfig `json:"source"`

// installNamespace is a reference to the Namespace in which the bundle of
// install is a required field used to configure the installation options
// for the ClusterExtension such as the installation namespace,
// the service account and the pre-flight check configuration.
//
// Below is a minimal example of an installation definition (in yaml):
// install:
// namespace: example-namespace
// serviceAccount:
// name: example-sa
Install ClusterExtensionInstallConfig `json:"install"`
}

const SourceTypeCatalog = "Catalog"

// SourceConfig is a discriminated union which selects the installation source.
// +union
// +kubebuilder:validation:XValidation:rule="self.sourceType == 'Catalog' && has(self.catalog)",message="sourceType Catalog requires catalog field"
type SourceConfig struct {
// sourceType is a required reference to the type of install source.
//
// Allowed values are ["Catalog"]
//
// When this field is set to "Catalog", information for determining the appropriate
// bundle of content to install will be fetched from ClusterCatalog resources existing
// on the cluster. When using the Catalog sourceType, the catalog field must also be set.
//
// +unionDiscriminator
// +kubebuilder:validation:Enum:="Catalog"
SourceType string `json:"sourceType"`

// catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog",
// and must be the only field defined for this sourceType.
//
// +optional.
Catalog *CatalogSource `json:"catalog,omitempty"`
}

// ClusterExtensionInstallConfig is a union which selects the clusterExtension installation config.
// ClusterExtensionInstallConfig requires the namespace and serviceAccount which should be used for the installation of packages.
// +union
type ClusterExtensionInstallConfig struct {
// namespace is a reference to the Namespace in which the bundle of
// content for the package referenced in the packageName field will be applied.
// The bundle may contain cluster-scoped resources or resources that are
// applied to other Namespaces. This Namespace is expected to exist.
//
// installNamespace is required, immutable, and follows the DNS label standard
// namespace is required, immutable, and follows the DNS label standard
// as defined in [RFC 1123]. This means that valid values:
// - Contain no more than 63 characters
// - Contain only lowercase alphanumeric characters or '-'
Expand All @@ -89,17 +130,8 @@ type ClusterExtensionSpec struct {
//
//+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
//+kubebuilder:validation:MaxLength:=63
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="installNamespace is immutable"
InstallNamespace string `json:"installNamespace"`

// 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.
//
// When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation.
//
// When not specified, the default configuration for each preflight check will be used.
//
//+optional
Preflight *PreflightConfig `json:"preflight,omitempty"`
//+kubebuilder:validation:XValidation:rule="self == oldSelf",message="namespace is immutable"
Namespace string `json:"namespace"`

// serviceAccount is a required reference to a ServiceAccount that exists
// in the installNamespace. The provided ServiceAccount is used to install and
Expand All @@ -110,31 +142,15 @@ type ClusterExtensionSpec struct {
// appropriate permissions to perform the necessary operations on all the
// resources that are included in the bundle of content being applied.
ServiceAccount ServiceAccountReference `json:"serviceAccount"`
}

const SourceTypeCatalog = "Catalog"

// SourceConfig is a discriminated union which selects the installation source.
// +union
// +kubebuilder:validation:XValidation:rule="self.sourceType == 'Catalog' && has(self.catalog)",message="sourceType Catalog requires catalog field"
type SourceConfig struct {
// sourceType is a required reference to the type of install source.
//
// Allowed values are ["Catalog"]
// 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.
//
// When this field is set to "Catalog", information for determining the appropriate
// bundle of content to install will be fetched from ClusterCatalog resources existing
// on the cluster. When using the Catalog sourceType, the catalog field must also be set.
// When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation.
//
// +unionDiscriminator
// +kubebuilder:validation:Enum:="Catalog"
SourceType string `json:"sourceType"`

// catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog",
// and must be the only field defined for this sourceType.
// When not specified, the default configuration for each preflight check will be used.
//
// +optional.
Catalog *CatalogSource `json:"catalog,omitempty"`
//+optional
Preflight *PreflightConfig `json:"preflight,omitempty"`
}

// CatalogSource defines the required fields for catalog source.
Expand Down Expand Up @@ -463,24 +479,9 @@ type BundleMetadata struct {

// ClusterExtensionStatus defines the observed state of ClusterExtension.
type ClusterExtensionStatus struct {
// installedBundle is a representation of the currently installed bundle.
//
// A "bundle" is a versioned set of content that represents the resources that
// need to be applied to a cluster to install a package.
//
// This field is only updated once a bundle has been successfully installed and
// once set will only be updated when a new version of the bundle has
// successfully replaced the currently installed version.
//
//+optional
InstalledBundle *BundleMetadata `json:"installedBundle,omitempty"`
Install *ClusterExtensionInstallStatus `json:"install,omitempty"`

// resolvedBundle is a representation of the bundle that was identified during
// resolution to meet all installation/upgrade constraints and is slated to be
// installed or upgraded to.
//
//+optional
ResolvedBundle *BundleMetadata `json:"resolvedBundle,omitempty"`
Resolution *ClusterExtensionResolutionStatus `json:"resolution,omitempty"`

// conditions is a representation of the current state for this ClusterExtension.
// The status is represented by a set of "conditions".
Expand Down Expand Up @@ -514,6 +515,29 @@ type ClusterExtensionStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

type ClusterExtensionInstallStatus struct {
// bundle is a representation of the currently installed bundle.
//
// A "bundle" is a versioned set of content that represents the resources that
// need to be applied to a cluster to install a package.
//
// This field is only updated once a bundle has been successfully installed and
// once set will only be updated when a new version of the bundle has
// successfully replaced the currently installed version.
//
//+optional
Bundle *BundleMetadata `json:"bundle,omitempty"`
}

type ClusterExtensionResolutionStatus struct {
// bundle is a representation of the bundle that was identified during
// resolution to meet all installation/upgrade constraints and is slated to be
// installed or upgraded to.
//
//+optional
Bundle *BundleMetadata `json:"bundle,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:resource:scope=Cluster
//+kubebuilder:subresource:status
Expand Down
84 changes: 70 additions & 14 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func main() {
helmclient.StorageDriverMapper(action.ChunkedStorageDriverMapper(coreClient, mgr.GetAPIReader(), systemNamespace)),
helmclient.ClientNamespaceMapper(func(obj client.Object) (string, error) {
ext := obj.(*ocv1alpha1.ClusterExtension)
return ext.Spec.InstallNamespace, nil
return ext.Spec.Install.Namespace, nil
}),
helmclient.ClientRestConfigMapper(clientRestConfigMapper),
)
Expand Down
Loading