Skip to content

Commit

Permalink
add .spec.install.valuesSources and plumb through new conversion logic
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Lanford <[email protected]>
  • Loading branch information
joelanford committed Oct 31, 2024
1 parent 13bb889 commit ba71ce0
Show file tree
Hide file tree
Showing 7 changed files with 504 additions and 12 deletions.
101 changes: 101 additions & 0 deletions api/v1alpha1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/operator-framework/operator-controller/internal/conditionsets"
Expand Down Expand Up @@ -150,6 +152,105 @@ type ClusterExtensionInstallConfig struct {
//
//+optional
Preflight *PreflightConfig `json:"preflight,omitempty"`

// valuesSources is a list of sources from which to obtain arbitrary values that
// provide configuration for the installation of bundles managed by the
// ClusterExtension.
//
// valuesSources is optional. When not specified, the package manager will use
// the default configuration of the resolved bundle.
//
// If multiple valuesSources are specified, the values are merged in the order
// they are specified. Values from later sources will override values from earlier
// sources.
//
// Bundles can optionally provide a schema for these values. When bundles provide
// a schema, it is used to validate these values before proceeding with the
// installation. Validation errors are reported via the ClusterExtension status.
//
//+optional
ValuesSources []ValuesSource `json:"valuesSources,omitempty"`
}

type ValuesSourceType string

const (
ValuesSourceTypeInline ValuesSourceType = "Inline"
ValuesSourceTypeConfigMap ValuesSourceType = "ConfigMap"
ValuesSourceTypeSecret ValuesSourceType = "Secret"
)

// ValuesSource is a discriminated union of possible sources for values.
// ValuesSource contains the sourcing information for those values.
// +union
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Inline' ?has(self.inline) : !has(self.inline)",message="inline is required when type is Inline, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'ConfigMap' ?has(self.configMap) : !has(self.configMap)",message="configMap is required when type is ConfigMap, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Secret' ?has(self.secret) : !has(self.secret)",message="secret is required when type is Secret, and forbidden otherwise"
type ValuesSource struct {
// type is a reference to the type of source the values are sourced from.
// type is required.
//
// The allowed values are "Inline", "ConfigMap", and "Secret".
//
// When set to "Inline", the values are sourced directly from the inlined content.
// When using an inline source, the inline field must be set and must be the only field defined for this type.
//
// When set to "ConfigMap", the values are sourced from the specified ConfigMap in the installNamespace.
// When using a ConfigMap source, the configMap field must be set and must be the only field defined for this type.
//
// When set to "Secret", the values are sourced from the specified Secret in the installNamespace.
// When using a Secret source, the secret field must be set and must be the only field defined for this type.
//
// +unionDiscriminator
// +kubebuilder:validation:Enum:="Inline";"ConfigMap";"Secret"
// +kubebuilder:validation:Required
Type ValuesSourceType `json:"type"`

// inline is a map of arbitrary key-value pairs.
//
// Inlined values are useful for small, simple configurations that do not
// include sensitive information.
//
//+kubebuilder:pruning:PreserveUnknownFields
//+kubebuilder:validation:Type=object
//+kubebuilder:validation:Schemaless
//+optional
Inline *apiextensionsv1.JSON `json:"inline,omitempty"`

// configMap is a reference to a key in a specific ConfigMap in the installNamespace.
// The referenced ConfigMap is expected to contain the specified key, whose value
// contains the desired configuration.
//
// ConfigMaps are useful for storing larger, more complex configurations that do
// not include sensitive information.
//
// The service account provided in the spec.install field must have 'get' permission in
// order to read the referenced ConfigMap.
//
//+optional
ConfigMap *LocalObjectReferenceWithKey `json:"configMap,omitempty"`

// secret is a reference to a key in a specific Secret in the installNamespace.
// The referenced Secret is expected to contain the specified key, whose value
// contains the desired configuration.
//
// Secrets are useful for storing larger, more complex configurations or
// configurations that include sensitive information.
//
// The service account provided in the spec.install field must have 'get' permission in
// order to read the referenced Secret.
//
//+optional
Secret *LocalObjectReferenceWithKey `json:"secret,omitempty"`
}

type LocalObjectReferenceWithKey struct {
corev1.LocalObjectReference `json:",inline"`

// key is a reference to a key in the data field of
// the referenced object.
//+kubebuilder:validation:Required
Key string `json:"key"`
}

// CatalogSource defines the required fields for catalog source.
Expand Down
58 changes: 56 additions & 2 deletions api/v1alpha1/zz_generated.deepcopy.go

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

1 change: 1 addition & 0 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ func main() {
}

applier := &applier.Helm{
ActionConfigGetter: cfgGetter,
ActionClientGetter: acg,
Preflights: preflights,
}
Expand Down
126 changes: 126 additions & 0 deletions config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,132 @@ spec:
required:
- name
type: object
valuesSources:
description: |-
valuesSources is a list of sources from which to obtain arbitrary values that
provide configuration for the installation of bundles managed by the
ClusterExtension.
valuesSources is optional. When not specified, the package manager will use
the default configuration of the resolved bundle.
If multiple valuesSources are specified, the values are merged in the order
they are specified. Values from later sources will override values from earlier
sources.
Bundles can optionally provide a schema for these values. When bundles provide
a schema, it is used to validate these values before proceeding with the
installation. Validation errors are reported via the ClusterExtension status.
items:
description: |-
ValuesSource is a discriminated union of possible sources for values.
ValuesSource contains the sourcing information for those values.
properties:
configMap:
description: |-
configMap is a reference to a key in a specific ConfigMap in the installNamespace.
The referenced ConfigMap is expected to contain the specified key, whose value
contains the desired configuration.
ConfigMaps are useful for storing larger, more complex configurations that do
not include sensitive information.
The service account provided in the spec.install field must have 'get' permission in
order to read the referenced ConfigMap.
properties:
key:
description: |-
key is a reference to a key in the data field of
the referenced object.
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
required:
- key
type: object
x-kubernetes-map-type: atomic
inline:
description: |-
inline is a map of arbitrary key-value pairs.
Inlined values are useful for small, simple configurations that do not
include sensitive information.
type: object
x-kubernetes-preserve-unknown-fields: true
secret:
description: |-
secret is a reference to a key in a specific Secret in the installNamespace.
The referenced Secret is expected to contain the specified key, whose value
contains the desired configuration.
Secrets are useful for storing larger, more complex configurations or
configurations that include sensitive information.
The service account provided in the spec.install field must have 'get' permission in
order to read the referenced Secret.
properties:
key:
description: |-
key is a reference to a key in the data field of
the referenced object.
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
required:
- key
type: object
x-kubernetes-map-type: atomic
type:
description: |-
type is a reference to the type of source the values are sourced from.
type is required.
The allowed values are "Inline", "ConfigMap", and "Secret".
When set to "Inline", the values are sourced directly from the inlined content.
When using an inline source, the inline field must be set and must be the only field defined for this type.
When set to "ConfigMap", the values are sourced from the specified ConfigMap in the installNamespace.
When using a ConfigMap source, the configMap field must be set and must be the only field defined for this type.
When set to "Secret", the values are sourced from the specified Secret in the installNamespace.
When using a Secret source, the secret field must be set and must be the only field defined for this type.
enum:
- Inline
- ConfigMap
- Secret
type: string
required:
- type
type: object
x-kubernetes-validations:
- message: inline is required when type is Inline, and forbidden
otherwise
rule: 'has(self.type) && self.type == ''Inline'' ?has(self.inline)
: !has(self.inline)'
- message: configMap is required when type is ConfigMap, and
forbidden otherwise
rule: 'has(self.type) && self.type == ''ConfigMap'' ?has(self.configMap)
: !has(self.configMap)'
- message: secret is required when type is Secret, and forbidden
otherwise
rule: 'has(self.type) && self.type == ''Secret'' ?has(self.secret)
: !has(self.secret)'
type: array
required:
- namespace
- serviceAccount
Expand Down
Loading

0 comments on commit ba71ce0

Please sign in to comment.