-
Notifications
You must be signed in to change notification settings - Fork 11
ESO-101: Restructures and renames ExternalSecrets API to ExternalSecretsConfig #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
5e5a943
f52c2a4
ffb8d54
70868e2
7b13b10
361b200
314e1fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,7 +55,7 @@ OPERATOR_SDK_VERSION ?= v1.39.0 | |
# Image URL to use all building/pushing image targets | ||
IMG ?= openshift.io/external-secrets-operator:latest | ||
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. | ||
ENVTEST_K8S_VERSION = 1.31.0 | ||
ENVTEST_K8S_VERSION = 1.32.0 | ||
|
||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) | ||
ifeq (,$(shell go env GOBIN)) | ||
|
@@ -127,8 +127,11 @@ vet: ## Run go vet against code. | |
go vet ./... | ||
|
||
.PHONY: test | ||
test: manifests generate fmt vet envtest ## Run tests. | ||
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out | ||
test: manifests generate fmt vet envtest test-apis test-unit ## Run tests. | ||
|
||
.PHONY: test-unit | ||
test-unit: vet ## Run unit tests. | ||
go test $$(go list ./... | grep -vE 'test/[e2e|apis|utils]') -coverprofile cover.out | ||
|
||
update-operand-manifests: helm yq | ||
hack/update-external-secrets-manifests.sh $(EXTERNAL_SECRETS_VERSION) | ||
|
@@ -250,6 +253,7 @@ YQ = $(LOCALBIN)/yq | |
HELM ?= $(LOCALBIN)/helm | ||
REFERENCE_DOC_GENERATOR ?= $(LOCALBIN)/crd-ref-docs | ||
GOVULNCHECK ?= $(LOCALBIN)/govulncheck | ||
GINKGO ?= $(LOCALBIN)/ginkgo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [claude-generated] Good documentation of the ignored vulnerabilities with links to vulnerability details. The added vulnerabilities (GO-2025-3956, GO-2025-3915) appear to be in vendored dependencies, which is appropriate to ignore if they don't affect the operator code. |
||
|
||
## Tool Versions | ||
YQ_VERSION = v4.45.2 | ||
|
@@ -283,11 +287,15 @@ crd-ref-docs: $(LOCALBIN) ## Download crd-ref-docs locally if necessary. | |
govulncheck: $(LOCALBIN) ## Download govulncheck locally if necessary. | ||
$(call go-install-tool,$(GOVULNCHECK),golang.org/x/vuln/cmd/govulncheck) | ||
|
||
.PHONY: ginkgo | ||
ginkgo: $(LOCALBIN) ## Download ginkgo locally if necessary. | ||
$(call go-install-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [claude-generated] The test structure changes properly separate API integration tests from unit tests. The test-apis target using ginkgo is well-implemented for running focused API validation tests. |
||
|
||
# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist | ||
# $1 - target path with name of binary | ||
# $2 - package url which can be installed | ||
define go-install-tool | ||
@[ -f "$(1)" ] || { \ | ||
@{ \ | ||
set -e; \ | ||
package=$(2) ;\ | ||
echo "Downloading $${package}" ;\ | ||
|
@@ -409,9 +417,22 @@ docs: crd-ref-docs | |
|
||
## perform vulnerabilities scan using govulncheck. | ||
.PHONY: govulnscan | ||
#GO-2025-3547 and GO-2025-3521 containing code is not directly used in the operator, hence will be ignored. | ||
KNOWN_VULNERABILITIES:="GO-2025-3547|GO-2025-3521" | ||
#The ignored vulnerabilities are not in the operator code, but in the vendored packages. | ||
# - https://pkg.go.dev/vuln/GO-2025-3956 | ||
# - https://pkg.go.dev/vuln/GO-2025-3915 | ||
# - https://pkg.go.dev/vuln/GO-2025-3547 | ||
# _ https://pkg.go.dev/vuln/GO-2025-3521 | ||
KNOWN_VULNERABILITIES:="GO-2025-3547|GO-2025-3521|GO-2025-3956|GO-2025-3915" | ||
govulnscan: govulncheck $(OUTPUTS_PATH) ## Run govulncheck | ||
- $(GOVULNCHECK) ./... > $(OUTPUTS_PATH)/govulcheck.results 2>&1 | ||
$(eval reported_vulnerabilities = $(strip $(shell grep "pkg.go.dev" $(OUTPUTS_PATH)/govulcheck.results | ([ -n $KNOWN_VULNERABILITIES ] && grep -Ev $(KNOWN_VULNERABILITIES) || cat) | wc -l))) | ||
@(if [ $(reported_vulnerabilities) -ne 0 ]; then echo -e "\n-- ERROR -- $(reported_vulnerabilities) new vulnerabilities reported, please check\n"; exit 1; fi) | ||
|
||
# Utilize controller-runtime provided envtest for API integration test | ||
.PHONY: test-apis ## Run only the api integration tests. | ||
test-apis: envtest ginkgo | ||
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" ./hack/test-apis.sh | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf $(LOCALBIN) $(OUTPUTS_PATH) cover.out dist |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func init() { | ||
SchemeBuilder.Register(&ExternalSecretsConfig{}, &ExternalSecretsConfigList{}) | ||
} | ||
|
||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
// +kubebuilder:object:root=true | ||
|
||
// ExternalSecretsConfigList is a list of ExternalSecretsConfig objects. | ||
type ExternalSecretsConfigList struct { | ||
metav1.TypeMeta `json:",inline"` | ||
|
||
// metadata is the standard list's metadata. | ||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata | ||
metav1.ListMeta `json:"metadata"` | ||
Items []ExternalSecretsConfig `json:"items"` | ||
} | ||
|
||
// +genclient | ||
// +genclient:nonNamespaced | ||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
// +kubebuilder:object:root=true | ||
// +kubebuilder:subresource:status | ||
// +kubebuilder:resource:path=externalsecretsconfigs,scope=Cluster,categories={external-secrets-operator, external-secrets},shortName=esc;externalsecretsconfig;esconfig | ||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status" | ||
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message" | ||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" | ||
// +kubebuilder:metadata:labels={"app.kubernetes.io/name=externalsecretsconfig", "app.kubernetes.io/part-of=external-secrets-operator"} | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// ExternalSecretsConfig describes configuration and information about the managed external-secrets deployment. | ||
// The name must be `cluster` as ExternalSecretsConfig is a singleton, allowing only one instance per cluster. | ||
// | ||
// When an ExternalSecretsConfig is created, the controller installs the external-secrets and keeps it in the desired state. | ||
// | ||
// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="ExternalSecretsConfig is a singleton, .metadata.name must be 'cluster'" | ||
// +operator-sdk:csv:customresourcedefinitions:displayName="ExternalSecretsConfig" | ||
type ExternalSecretsConfig struct { | ||
metav1.TypeMeta `json:",inline"` | ||
|
||
// metadata is the standard object's metadata. | ||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata | ||
metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
||
// spec is the specification of the desired behavior of the ExternalSecretsConfig. | ||
Spec ExternalSecretsConfigSpec `json:"spec,omitempty"` | ||
|
||
// status is the most recently observed status of the ExternalSecretsConfig. | ||
Status ExternalSecretsConfigStatus `json:"status,omitempty"` | ||
} | ||
|
||
// ExternalSecretsConfigSpec is for configuring the external-secrets operand behavior. | ||
// +kubebuilder:validation:XValidation:rule="!has(self.plugins) || !has(self.plugins.bitwardenSecretManagerProvider) || !has(self.plugins.bitwardenSecretManagerProvider.mode) || self.plugins.bitwardenSecretManagerProvider.mode != 'Enabled' || has(self.plugins.bitwardenSecretManagerProvider.secretRef) || (has(self.controllerConfig) && has(self.controllerConfig.certProvider) && has(self.controllerConfig.certProvider.certManager) && has(self.controllerConfig.certProvider.certManager.mode) && self.controllerConfig.certProvider.certManager.mode == 'Enabled')",message="secretRef or certManager must be configured when bitwardenSecretManagerProvider plugin is enabled" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [claude-generated] The XValidation rule for bitwardenSecretManagerProvider is quite complex and could benefit from breaking down into multiple smaller validation rules for better readability and error messages. |
||
type ExternalSecretsConfigSpec struct { | ||
// appConfig is for specifying the configurations for the `external-secrets` operand. | ||
// +kubebuilder:validation:Optional | ||
ApplicationConfig ApplicationConfig `json:"appConfig,omitempty"` | ||
|
||
// plugins is for configuring the optional provider plugins. | ||
// +kubebuilder:validation:Optional | ||
Plugins PluginsConfig `json:"plugins,omitempty"` | ||
|
||
// controllerConfig is for specifying the configurations for the controller to use while installing the `external-secrets` operand and the plugins. | ||
// +kubebuilder:validation:Optional | ||
ControllerConfig ControllerConfig `json:"controllerConfig,omitempty"` | ||
} | ||
|
||
// ExternalSecretsConfigStatus is the most recently observed status of the ExternalSecretsConfig. | ||
type ExternalSecretsConfigStatus struct { | ||
// conditions holds information of the current state of the external-secrets deployment. | ||
ConditionalStatus `json:",inline"` | ||
|
||
// externalSecretsImage is the name of the image and the tag used for deploying external-secrets. | ||
ExternalSecretsImage string `json:"externalSecretsImage,omitempty"` | ||
|
||
// BitwardenSDKServerImage is the name of the image and the tag used for deploying bitwarden-sdk-server. | ||
BitwardenSDKServerImage string `json:"bitwardenSDKServerImage,omitempty"` | ||
} | ||
|
||
// ApplicationConfig is for specifying the configurations for the external-secrets operand. | ||
type ApplicationConfig struct { | ||
// operatingNamespace is for restricting the external-secrets operations to the provided namespace. | ||
// When configured `ClusterSecretStore` and `ClusterExternalSecret` are implicitly disabled. | ||
// +kubebuilder:validation:MinLength:=1 | ||
// +kubebuilder:validation:MaxLength:=63 | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// +kubebuilder:validation:Optional | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [claude-generated] Consider adding validation to ensure operatingNamespace follows Kubernetes namespace naming conventions (RFC 1123 label names). |
||
OperatingNamespace string `json:"operatingNamespace,omitempty"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in above claude comment, would it be better to validate OperatingNamespace as per RFC 1123 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. operatingNamespace is as per the RFC 1123 DNS Labels, which allows max of 63 characters for namespace. |
||
|
||
// webhookConfig is for configuring external-secrets webhook specifics. | ||
// +kubebuilder:validation:Optional | ||
WebhookConfig *WebhookConfig `json:"webhookConfig,omitempty"` | ||
|
||
// +kubebuilder:validation:Optional | ||
CommonConfigs `json:",inline"` | ||
} | ||
|
||
// ControllerConfig is for specifying the configurations for the controller to use while installing the `external-secrets` operand and the plugins. | ||
type ControllerConfig struct { | ||
// certProvider is for defining the configuration for certificate providers used to manage TLS certificates for webhook and plugins. | ||
// +kubebuilder:validation:Optional | ||
CertProvider *CertProvidersConfig `json:"certProvider,omitempty"` | ||
|
||
// labels to apply to all resources created for the external-secrets operand deployment. | ||
// This field can have a maximum of 20 entries. | ||
// +mapType=granular | ||
// +kubebuilder:validation:MinProperties:=0 | ||
// +kubebuilder:validation:MaxProperties:=20 | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// +kubebuilder:validation:Optional | ||
Labels map[string]string `json:"labels,omitempty"` | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// periodicReconcileInterval specifies the time interval in seconds for periodic reconciliation by the operator. | ||
// This controls how often the operator checks resources created for external-secrets operand to ensure they remain in desired state. | ||
// Interval can have value between 120-18000 seconds (2 minutes to 5 hours). Defaults to 300 seconds (5 minutes) if not specified. | ||
// +kubebuilder:default:=300 | ||
// +kubebuilder:validation:Minimum:=120 | ||
// +kubebuilder:validation:Maximum:=18000 | ||
// +kubebuilder:validation:Optional | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [claude-generated] The periodicReconcileInterval field has good validation constraints. Consider documenting the performance implications of different interval values in the field description. |
||
PeriodicReconcileInterval uint32 `json:"periodicReconcileInterval,omitempty"` | ||
} | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// BitwardenSecretManagerProvider is for enabling the bitwarden secrets manager provider and for setting up the additional service required for connecting with the bitwarden server. | ||
type BitwardenSecretManagerProvider struct { | ||
// mode indicates bitwarden secrets manager provider state, which can be indicated by setting Enabled or Disabled. | ||
// Enabled: Enables the Bitwarden provider plugin. The operator will ensure the plugin is deployed and its state is synchronized. | ||
// Disabled: Disables reconciliation of the Bitwarden provider plugin. The plugin and its resources will remain in their current state and will not be managed by the operator. | ||
// +kubebuilder:validation:Enum:=Enabled;Disabled | ||
// +kubebuilder:default:=Disabled | ||
// +kubebuilder:validation:Optional | ||
Mode Mode `json:"mode,omitempty"` | ||
|
||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// SecretRef is the Kubernetes secret containing the TLS key pair to be used for the bitwarden server. | ||
// The issuer in CertManagerConfig will be utilized to generate the required certificate if the secret reference is not provided and CertManagerConfig is configured. | ||
// The key names in secret for certificate must be `tls.crt`, for private key must be `tls.key` and for CA certificate key name must be `ca.crt`. | ||
// +kubebuilder:validation:Optional | ||
SecretRef *SecretReference `json:"secretRef,omitempty"` | ||
} | ||
|
||
// WebhookConfig is for configuring external-secrets webhook specifics. | ||
type WebhookConfig struct { | ||
// CertificateCheckInterval is for configuring the polling interval to check the certificate validity. | ||
// +kubebuilder:default:="5m" | ||
// +kubebuilder:validation:Optional | ||
CertificateCheckInterval *metav1.Duration `json:"certificateCheckInterval,omitempty"` | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// CertManagerConfig is for configuring cert-manager specifics. | ||
// +kubebuilder:validation:XValidation:rule="self.mode != 'Enabled' || has(self.issuerRef)",message="issuerRef must be provided when mode is set to Enabled." | ||
// +kubebuilder:validation:XValidation:rule="has(self.injectAnnotations) && self.injectAnnotations != 'false' ? self.mode != 'Disabled' : true",message="injectAnnotations can only be set when mode is set to Enabled." | ||
type CertManagerConfig struct { | ||
// mode indicates whether to use cert-manager for certificate management, instead of built-in cert-controller. | ||
// Enabled: Makes use of cert-manager for obtaining the certificates for webhook server and other components. | ||
// Disabled: Makes use of in-built cert-controller for obtaining the certificates for webhook server, which is the default behavior. | ||
// This field is immutable once set. | ||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="mode is immutable once set" | ||
// +kubebuilder:validation:Enum:=Enabled;Disabled | ||
// +kubebuilder:default:=Disabled | ||
// +kubebuilder:validation:Required | ||
Mode Mode `json:"mode,omitempty"` | ||
|
||
// injectAnnotations is for adding the `cert-manager.io/inject-ca-from` annotation to the webhooks and CRDs to automatically setup webhook to use the cert-manager CA. This requires CA Injector to be enabled in cert-manager. | ||
// Use `true` or `false` to indicate the preference. This field is immutable once set. | ||
// +kubebuilder:validation:Enum:="true";"false" | ||
// +kubebuilder:default:="false" | ||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="injectAnnotations is immutable once set" | ||
// +kubebuilder:validation:Optional | ||
InjectAnnotations string `json:"injectAnnotations,omitempty"` | ||
bharath-b-rh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// issuerRef contains details of the referenced object used for obtaining certificates. | ||
// When `issuerRef.Kind` is `Issuer`, it must exist in the `external-secrets` namespace. | ||
// This field is immutable once set. | ||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="issuerRef is immutable once set" | ||
// +kubebuilder:validation:XValidation:rule="!has(self.kind) || self.kind.lowerAscii() == 'issuer' || self.kind.lowerAscii() == 'clusterissuer'",message="kind must be either 'Issuer' or 'ClusterIssuer'" | ||
// +kubebuilder:validation:XValidation:rule="!has(self.group) || self.group.lowerAscii() == 'cert-manager.io'",message="group must be 'cert-manager.io'" | ||
// +kubebuilder:validation:Optional | ||
IssuerRef ObjectReference `json:"issuerRef,omitempty"` | ||
|
||
// certificateDuration is the validity period of the webhook certificate. | ||
// +kubebuilder:default:="8760h" | ||
// +kubebuilder:validation:Optional | ||
CertificateDuration *metav1.Duration `json:"certificateDuration,omitempty"` | ||
|
||
// certificateRenewBefore is the ahead time to renew the webhook certificate before expiry. | ||
// +kubebuilder:default:="30m" | ||
// +kubebuilder:validation:Optional | ||
CertificateRenewBefore *metav1.Duration `json:"certificateRenewBefore,omitempty"` | ||
} | ||
|
||
// PluginsConfig is for configuring the optional plugins. | ||
type PluginsConfig struct { | ||
// bitwardenSecretManagerProvider is for enabling the bitwarden secrets manager provider plugin for connecting with the bitwarden secrets manager. | ||
// +kubebuilder:validation:Optional | ||
BitwardenSecretManagerProvider *BitwardenSecretManagerProvider `json:"bitwardenSecretManagerProvider,omitempty"` | ||
} | ||
|
||
// CertProvidersConfig defines the configuration for certificate providers used to manage TLS certificates for webhook and plugins. | ||
type CertProvidersConfig struct { | ||
// certManager is for configuring cert-manager provider specifics. | ||
// +kubebuilder:validation:Optional | ||
CertManager *CertManagerConfig `json:"certManager,omitempty"` | ||
} |
Uh oh!
There was an error while loading. Please reload this page.