diff --git a/.ci-operator.yaml b/.ci-operator.yaml index 1a05e6069..df7900c64 100644 --- a/.ci-operator.yaml +++ b/.ci-operator.yaml @@ -1,4 +1,4 @@ build_root_image: name: tools namespace: openstack-k8s-operators - tag: ci-build-root-golang-1.24-sdk-1.31 + tag: ci-build-root-golang-1.24-sdk-1.41.1 diff --git a/.github/workflows/force-bump-pr-manual.yaml b/.github/workflows/force-bump-pr-manual.yaml index da0f93aa8..b1ac8d4d0 100644 --- a/.github/workflows/force-bump-pr-manual.yaml +++ b/.github/workflows/force-bump-pr-manual.yaml @@ -9,6 +9,6 @@ jobs: with: operator_name: nova branch_name: ${{ github.ref_name }} - custom_image: quay.io/openstack-k8s-operators/openstack-k8s-operators-ci-build-tools:golang-1.24-sdk-1.31 + custom_image: quay.io/openstack-k8s-operators/openstack-k8s-operators-ci-build-tools:golang-1.24-sdk-1.41.1 secrets: FORCE_BUMP_PULL_REQUEST_PAT: ${{ secrets.FORCE_BUMP_PULL_REQUEST_PAT }} diff --git a/.github/workflows/force-bump-pr-scheduled.yaml b/.github/workflows/force-bump-pr-scheduled.yaml index aaf67adb1..1d34da741 100644 --- a/.github/workflows/force-bump-pr-scheduled.yaml +++ b/.github/workflows/force-bump-pr-scheduled.yaml @@ -10,6 +10,6 @@ jobs: uses: openstack-k8s-operators/openstack-k8s-operators-ci/.github/workflows/force-bump-branches.yaml@main with: operator_name: nova - custom_image: quay.io/openstack-k8s-operators/openstack-k8s-operators-ci-build-tools:golang-1.24-sdk-1.31 + custom_image: quay.io/openstack-k8s-operators/openstack-k8s-operators-ci-build-tools:golang-1.24-sdk-1.41.1 secrets: FORCE_BUMP_PULL_REQUEST_PAT: ${{ secrets.FORCE_BUMP_PULL_REQUEST_PAT }} diff --git a/.zuul.yaml b/.zuul.yaml index a8c06524c..bacdee407 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -189,7 +189,9 @@ merge-mode: rebase github-check: jobs: - - openstack-meta-content-provider + - openstack-meta-content-provider: + vars: + cifmw_install_yamls_sdk_version: v1.41.1 - nova-operator-kuttl - nova-operator-tempest-multinode - nova-operator-tempest-multinode-ceph @@ -223,6 +225,7 @@ cifmw_bop_openstack_release: master cifmw_bop_dlrn_baseurl: "https://trunk.rdoproject.org/centos9-master" cifmw_repo_setup_branch: master + cifmw_install_yamls_sdk_version: v1.41.1 - nova-operator-tempest-multinode: &job_vars override-checkout: main # when run from nova we need to ensure we list the nova-operator diff --git a/Dockerfile b/Dockerfile index 793dbb857..11d34a082 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN mkdir -p ${DEST_ROOT}/usr/local/bin/ RUN if [ ! -f $CACHITO_ENV_FILE ]; then go mod download ; fi # Build manager -RUN if [ -f $CACHITO_ENV_FILE ] ; then source $CACHITO_ENV_FILE ; fi ; env ${GO_BUILD_EXTRA_ENV_ARGS} go build ${GO_BUILD_EXTRA_ARGS} -a -o ${DEST_ROOT}/manager main.go +RUN if [ -f $CACHITO_ENV_FILE ] ; then source $CACHITO_ENV_FILE ; fi ; env ${GO_BUILD_EXTRA_ENV_ARGS} go build ${GO_BUILD_EXTRA_ARGS} -a -o ${DEST_ROOT}/manager cmd/main.go RUN cp -r templates ${DEST_ROOT}/templates diff --git a/Makefile b/Makefile index 415127b06..b41611c2c 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ endif # Set the Operator SDK version to use. By default, what is installed on the system is used. # This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit. -OPERATOR_SDK_VERSION ?= v1.31.0 +OPERATOR_SDK_VERSION ?= v1.41.1 # Image URL to use all building/pushing image targets DEFAULT_IMG ?= quay.io/openstack-k8s-operators/nova-operator:latest @@ -150,13 +150,13 @@ PROC_CMD = --procs ${PROCS} test: manifests generate fmt vet envtest ginkgo ## Run tests. KUBEBUILDER_ASSETS="$(shell $(ENVTEST) -v debug --bin-dir $(LOCALBIN) use $(ENVTEST_K8S_VERSION) -p path)" \ OPERATOR_TEMPLATES="$(PWD)/templates" \ - $(GINKGO) --trace --cover --coverpkg=../../pkg/...,../../controllers,../../api/v1beta1 --coverprofile cover.out --covermode=atomic --randomize-all ${PROC_CMD} $(GINKGO_ARGS) ./test/... + $(GINKGO) --trace --cover --coverpkg=../../internal/...,../../api/v1beta1 --coverprofile cover.out --covermode=atomic --randomize-all ${PROC_CMD} $(GINKGO_ARGS) ./test/... ##@ Build .PHONY: build build: generate fmt vet ## Build manager binary. - go build -o bin/manager main.go + go build -o bin/manager cmd/main.go .PHONY: run run: export METRICS_PORT?=24600 @@ -165,7 +165,7 @@ run: export PPROF_PORT?=8082 run: export ENABLE_WEBHOOKS?=false run: manifests generate fmt vet ## Run a controller from your host. /bin/bash hack/clean_local_webhook.sh - go run ./main.go -metrics-bind-address ":$(METRICS_PORT)" -health-probe-bind-address ":$(HEALTH_PORT)" -pprof-bind-address ":$(PPROF_PORT)" + go run ./cmd/main.go -metrics-bind-address ":$(METRICS_PORT)" -health-probe-bind-address ":$(HEALTH_PORT)" -pprof-bind-address ":$(PPROF_PORT)" # Extra vars which will be passed to the Docker-build @@ -216,7 +216,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest GINKGO ?= $(LOCALBIN)/ginkgo ## Tool Versions -KUSTOMIZE_VERSION ?= v3.8.7 +KUSTOMIZE_VERSION ?= v5.6.0 CONTROLLER_TOOLS_VERSION ?= v0.18.0 KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" diff --git a/PROJECT b/PROJECT index 89c2c00a5..237f3fd3d 100644 --- a/PROJECT +++ b/PROJECT @@ -1,6 +1,10 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html domain: openstack.org layout: -- go.kubebuilder.io/v3 +- go.kubebuilder.io/v4 plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {} diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go index 0a4f176b0..fbbc2f416 100644 --- a/api/v1beta1/common_types.go +++ b/api/v1beta1/common_types.go @@ -104,6 +104,7 @@ type PasswordSelector struct { PrefixMetadataCellsSecret string `json:"prefixMetadataCellsSecret"` } +// NovaImages defines container images used by top level Nova CR type NovaImages struct { // +kubebuilder:validation:Required // APIContainerImageURL @@ -116,6 +117,7 @@ type NovaImages struct { NovaCellImages `json:",inline"` } +// Default sets default image URLs for NovaImages func (r *NovaImages) Default(defaults NovaDefaults) { r.NovaCellImages.Default(defaults.NovaCellDefaults) if r.APIContainerImageURL == "" { @@ -126,6 +128,7 @@ func (r *NovaImages) Default(defaults NovaDefaults) { } } +// NovaCellImages defines container images used by NovaCell services type NovaCellImages struct { // +kubebuilder:validation:Required @@ -145,6 +148,7 @@ type NovaCellImages struct { NovaComputeContainerImageURL string `json:"computeContainerImageURL"` } +// Default sets default image URLs for NovaCellImages func (r *NovaCellImages) Default(defaults NovaCellDefaults) { if r.ConductorContainerImageURL == "" { r.ConductorContainerImageURL = defaults.ConductorContainerImageURL diff --git a/api/v1beta1/nova_webhook.go b/api/v1beta1/nova_webhook.go index b1abe25b6..b144b1601 100644 --- a/api/v1beta1/nova_webhook.go +++ b/api/v1beta1/nova_webhook.go @@ -35,7 +35,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/utils/ptr" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -60,15 +59,6 @@ func SetupNovaDefaults(defaults NovaDefaults) { novalog.Info("Nova defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *Nova) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-nova,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=nova,verbs=create;update,versions=v1beta1,name=mnova.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &Nova{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -121,15 +111,13 @@ func (spec *NovaSpecCore) Default() { } } -// NOTE: change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-nova,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=nova,verbs=create;update,versions=v1beta1,name=vnova.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &Nova{} -func (r *NovaSpecCore) ValidateCellTemplates(basePath *field.Path, namespace string) field.ErrorList { +// ValidateCellTemplates validates cell templates configuration +func (spec *NovaSpecCore) ValidateCellTemplates(basePath *field.Path, namespace string) field.ErrorList { var errors field.ErrorList - if _, ok := r.CellTemplates[Cell0Name]; !ok { + if _, ok := spec.CellTemplates[Cell0Name]; !ok { errors = append( errors, field.Required(basePath.Child("cellTemplates"), @@ -139,7 +127,7 @@ func (r *NovaSpecCore) ValidateCellTemplates(basePath *field.Path, namespace str cellMessageBusNames := make(map[string]string) - for name, cell := range r.CellTemplates { + for name, cell := range spec.CellTemplates { cellPath := basePath.Child("cellTemplates").Key(name) errors = append( errors, @@ -163,7 +151,7 @@ func (r *NovaSpecCore) ValidateCellTemplates(basePath *field.Path, namespace str cellMessageBusNames[cell.CellMessageBusInstance] = name } - if *cell.MetadataServiceTemplate.Enabled && *r.MetadataServiceTemplate.Enabled { + if *cell.MetadataServiceTemplate.Enabled && *spec.MetadataServiceTemplate.Enabled { errors = append( errors, field.Invalid( @@ -239,22 +227,22 @@ func (r *NovaSpecCore) ValidateCellTemplates(basePath *field.Path, namespace str } // ValidateAPIServiceTemplate - -func (r *NovaSpecCore) ValidateAPIServiceTemplate(basePath *field.Path, namespace string) field.ErrorList { +func (spec *NovaSpecCore) ValidateAPIServiceTemplate(basePath *field.Path, namespace string) field.ErrorList { errors := field.ErrorList{} // validate the service override key is valid errors = append(errors, service.ValidateRoutedOverrides( basePath.Child("apiServiceTemplate").Child("override").Child("service"), - r.APIServiceTemplate.Override.Service)...) + spec.APIServiceTemplate.Override.Service)...) errors = append(errors, ValidateAPIDefaultConfigOverwrite( basePath.Child("apiServiceTemplate").Child("defaultConfigOverwrite"), - r.APIServiceTemplate.DefaultConfigOverwrite)...) + spec.APIServiceTemplate.DefaultConfigOverwrite)...) errors = append(errors, - r.APIServiceTemplate.ValidateTopology( + spec.APIServiceTemplate.ValidateTopology( basePath.Child("apiServiceTemplate"), namespace)...) @@ -262,44 +250,44 @@ func (r *NovaSpecCore) ValidateAPIServiceTemplate(basePath *field.Path, namespac } // ValidateSchedulerServiceTemplate - -func (r *NovaSpecCore) ValidateSchedulerServiceTemplate(basePath *field.Path, namespace string) field.ErrorList { +func (spec *NovaSpecCore) ValidateSchedulerServiceTemplate(basePath *field.Path, namespace string) field.ErrorList { errors := field.ErrorList{} // validate the referenced TopologyRef errors = append(errors, - r.SchedulerServiceTemplate.ValidateTopology( + spec.SchedulerServiceTemplate.ValidateTopology( basePath.Child("schedulerServiceTemplate"), namespace)...) return errors } // ValidateCreate validates the NovaSpec during the webhook invocation. -func (r *NovaSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { - return r.NovaSpecCore.ValidateCreate(basePath, namespace) +func (spec *NovaSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { + return spec.NovaSpecCore.ValidateCreate(basePath, namespace) } // ValidateCreate validates the NovaSpecCore during the webhook invocation. It is // expected to be called by the validation webhook in the higher level meta // operator -func (r *NovaSpecCore) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { - errors := r.ValidateCellTemplates(basePath, namespace) - errors = append(errors, r.ValidateAPIServiceTemplate(basePath, namespace)...) - errors = append(errors, r.ValidateSchedulerServiceTemplate(basePath, namespace)...) +func (spec *NovaSpecCore) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { + errors := spec.ValidateCellTemplates(basePath, namespace) + errors = append(errors, spec.ValidateAPIServiceTemplate(basePath, namespace)...) + errors = append(errors, spec.ValidateSchedulerServiceTemplate(basePath, namespace)...) // validate TopologyRef override for top-level MetadataServiceTemplate errors = append(errors, - r.MetadataServiceTemplate.ValidateTopology( + spec.MetadataServiceTemplate.ValidateTopology( basePath.Child("metadataServiceTemplate"), namespace)...) errors = append( errors, - r.MetadataServiceTemplate.ValidateDefaultConfigOverwrite( + spec.MetadataServiceTemplate.ValidateDefaultConfigOverwrite( basePath.Child("metadataServiceTemplate"))...) // validate top-level topology errors = append(errors, topologyv1.ValidateTopologyRef( - r.TopologyRef, *basePath.Child("topologyRef"), namespace)...) + spec.TopologyRef, *basePath.Child("topologyRef"), namespace)...) return errors } @@ -319,31 +307,31 @@ func (r *Nova) ValidateCreate() (admission.Warnings, error) { } // ValidateUpdate validates the NovaSpec during the webhook invocation. -func (r *NovaSpec) ValidateUpdate(old NovaSpec, basePath *field.Path, namespace string) field.ErrorList { - return r.NovaSpecCore.ValidateUpdate(old.NovaSpecCore, basePath, namespace) +func (spec *NovaSpec) ValidateUpdate(old NovaSpec, basePath *field.Path, namespace string) field.ErrorList { + return spec.NovaSpecCore.ValidateUpdate(old.NovaSpecCore, basePath, namespace) } // ValidateUpdate validates the NovaSpecCore during the webhook invocation. It is // expected to be called by the validation webhook in the higher level meta // operator -func (r *NovaSpecCore) ValidateUpdate(old NovaSpecCore, basePath *field.Path, namespace string) field.ErrorList { - errors := r.ValidateCellTemplates(basePath, namespace) +func (spec *NovaSpecCore) ValidateUpdate(old NovaSpecCore, basePath *field.Path, namespace string) field.ErrorList { + errors := spec.ValidateCellTemplates(basePath, namespace) // Validate top-level TopologyRef errors = append(errors, topologyv1.ValidateTopologyRef( - r.TopologyRef, *basePath.Child("topologyRef"), namespace)...) + spec.TopologyRef, *basePath.Child("topologyRef"), namespace)...) - errors = append(errors, r.ValidateAPIServiceTemplate(basePath, namespace)...) - errors = append(errors, r.ValidateSchedulerServiceTemplate(basePath, namespace)...) + errors = append(errors, spec.ValidateAPIServiceTemplate(basePath, namespace)...) + errors = append(errors, spec.ValidateSchedulerServiceTemplate(basePath, namespace)...) // validate TopologyRef override for top-level MetadataServiceTemplate errors = append(errors, - r.MetadataServiceTemplate.ValidateTopology( + spec.MetadataServiceTemplate.ValidateTopology( basePath.Child("metadataServiceTemplate"), namespace)...) errors = append( errors, - r.MetadataServiceTemplate.ValidateDefaultConfigOverwrite( + spec.MetadataServiceTemplate.ValidateDefaultConfigOverwrite( basePath.Child("metadataServiceTemplate"))...) return errors @@ -379,7 +367,7 @@ func (r *Nova) ValidateDelete() (admission.Warnings, error) { // SetDefaultRouteAnnotations sets HAProxy timeout values of the route // NOTE: it is used by ctlplane webhook on openstack-operator -func (r *NovaSpecCore) SetDefaultRouteAnnotations(annotations map[string]string) { +func (spec *NovaSpecCore) SetDefaultRouteAnnotations(annotations map[string]string) { const haProxyAnno = "haproxy.router.openshift.io/timeout" // Use a custom annotation to flag when the operator has set the default HAProxy timeout // With the annotation func determines when to overwrite existing HAProxy timeout with the APITimeout @@ -399,7 +387,7 @@ func (r *NovaSpecCore) SetDefaultRouteAnnotations(annotations map[string]string) return } - timeout := fmt.Sprintf("%ds", r.APITimeout) + timeout := fmt.Sprintf("%ds", spec.APITimeout) annotations[novaAnno] = timeout annotations[haProxyAnno] = timeout } diff --git a/api/v1beta1/novaapi_types.go b/api/v1beta1/novaapi_types.go index 603b32982..e2d2e7c55 100644 --- a/api/v1beta1/novaapi_types.go +++ b/api/v1beta1/novaapi_types.go @@ -240,16 +240,16 @@ func (n NovaAPI) GetSecret() string { } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaAPI) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaAPI) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaAPI) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaAPI) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaAPI) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaAPI) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novaapi_webhook.go b/api/v1beta1/novaapi_webhook.go index 6552dd023..705c398ea 100644 --- a/api/v1beta1/novaapi_webhook.go +++ b/api/v1beta1/novaapi_webhook.go @@ -30,7 +30,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -55,15 +54,6 @@ func SetupNovaAPIDefaults(defaults NovaAPIDefaults) { novaapilog.Info("NovaAPI defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaAPI) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novaapi,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaapis,verbs=create;update,versions=v1beta1,name=mnovaapi.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaAPI{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -80,9 +70,6 @@ func (spec *NovaAPISpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novaapi,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaapis,verbs=create;update,versions=v1beta1,name=vnovaapi.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaAPI{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type @@ -153,6 +140,7 @@ func (r *NovaAPI) ValidateDelete() (admission.Warnings, error) { return nil, nil } +// ValidateAPIDefaultConfigOverwrite validates the defaultConfigOverwrite for NovaAPI func ValidateAPIDefaultConfigOverwrite( basePath *field.Path, defaultConfigOverwrite map[string]string, diff --git a/api/v1beta1/novacell_types.go b/api/v1beta1/novacell_types.go index f0f80943f..091e60e00 100644 --- a/api/v1beta1/novacell_types.go +++ b/api/v1beta1/novacell_types.go @@ -308,6 +308,6 @@ func (instance NovaCell) IsReady() bool { } // GetSecret returns the value of the NovaCell.Spec.Secret -func (n NovaCell) GetSecret() string { - return n.Spec.Secret +func (instance NovaCell) GetSecret() string { + return instance.Spec.Secret } diff --git a/api/v1beta1/novacell_webhook.go b/api/v1beta1/novacell_webhook.go index 8ba74de00..96153652d 100644 --- a/api/v1beta1/novacell_webhook.go +++ b/api/v1beta1/novacell_webhook.go @@ -32,13 +32,13 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/utils/ptr" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" ) +// CRDNameRegex is the regex pattern for validating CRD names const CRDNameRegex = "^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" // NovaCellDefaults - @@ -60,15 +60,6 @@ func SetupNovaCellDefaults(defaults NovaCellDefaults) { novacelllog.Info("NovaCell defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaCell) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novacell,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacells,verbs=create;update,versions=v1beta1,name=mnovacell.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaCell{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -99,27 +90,24 @@ func (spec *NovaCellSpec) Default() { } } -// NOTE: change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novacell,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacells,verbs=create;update,versions=v1beta1,name=vnovacell.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaCell{} -func (r *NovaCellSpec) validate(basePath *field.Path, namespace string) field.ErrorList { +func (spec *NovaCellSpec) validate(basePath *field.Path, namespace string) field.ErrorList { var errors field.ErrorList - if r.CellName == Cell0Name { + if spec.CellName == Cell0Name { errors = append( - errors, r.MetadataServiceTemplate.ValidateCell0( + errors, spec.MetadataServiceTemplate.ValidateCell0( basePath.Child("metadataServiceTemplate"))..., ) errors = append( - errors, r.NoVNCProxyServiceTemplate.ValidateCell0( + errors, spec.NoVNCProxyServiceTemplate.ValidateCell0( basePath.Child("noVNCProxyServiceTemplate"))..., ) errors = append( errors, ValidateNovaComputeCell0( - basePath.Child("novaComputeTemplates"), len(r.NovaComputeTemplates))...) + basePath.Child("novaComputeTemplates"), len(spec.NovaComputeTemplates))...) } // validate topology if passed to the CellSpec (regardless of CellName). @@ -127,24 +115,24 @@ func (r *NovaCellSpec) validate(basePath *field.Path, namespace string) field.Er // be validated for the underlying components (metadata, conductor, // novncproxy, compute templates). errors = append(errors, topologyv1.ValidateTopologyRef( - r.TopologyRef, *basePath.Child("topologyRef"), namespace)...) + spec.TopologyRef, *basePath.Child("topologyRef"), namespace)...) errors = append(errors, - r.MetadataServiceTemplate.ValidateTopology( + spec.MetadataServiceTemplate.ValidateTopology( basePath.Child("metadataServiceTemplate"), namespace)...) errors = append(errors, - r.NoVNCProxyServiceTemplate.ValidateTopology( + spec.NoVNCProxyServiceTemplate.ValidateTopology( basePath.Child("noVNCProxyServiceTemplate"), namespace)...) errors = append(errors, - r.ConductorServiceTemplate.ValidateTopology( + spec.ConductorServiceTemplate.ValidateTopology( basePath.Child("conductorServiceTemplate"), namespace)...) - for computeName, computeTemplate := range r.NovaComputeTemplates { + for computeName, computeTemplate := range spec.NovaComputeTemplates { if computeTemplate.ComputeDriver == IronicDriver { errors = append( errors, computeTemplate.ValidateIronicDriverReplicas( @@ -168,18 +156,19 @@ func (r *NovaCellSpec) validate(basePath *field.Path, namespace string) field.Er errors = append( errors, ValidateCellName( - basePath.Child("cellName"), r.CellName)..., + basePath.Child("cellName"), spec.CellName)..., ) errors = append( errors, - r.DBPurge.Validate(basePath.Child("dbPurge"))..., + spec.DBPurge.Validate(basePath.Child("dbPurge"))..., ) return errors } -func (r *NovaCellSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { - return r.validate(basePath, namespace) +// ValidateCreate validates the NovaCellSpec during the webhook invocation +func (spec *NovaCellSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { + return spec.validate(basePath, namespace) } // ValidateCreate implements webhook.Validator so a webhook will be registered for the type @@ -199,8 +188,9 @@ func (r *NovaCell) ValidateCreate() (admission.Warnings, error) { return nil, nil } -func (r *NovaCellSpec) ValidateUpdate(old NovaCellSpec, basePath *field.Path, namespace string) field.ErrorList { - return r.validate(basePath, namespace) +// ValidateUpdate validates the NovaCellSpec during the webhook invocation +func (spec *NovaCellSpec) ValidateUpdate(old NovaCellSpec, basePath *field.Path, namespace string) field.ErrorList { + return spec.validate(basePath, namespace) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type @@ -237,7 +227,6 @@ func (r *NovaCell) ValidateDelete() (admission.Warnings, error) { // ValidateCellName validates the cell name. It is expected to be called // from various webhooks. - func ValidateCellName(path *field.Path, cellName string) field.ErrorList { var errors field.ErrorList if len(cellName) > 35 { diff --git a/api/v1beta1/novacompute_types.go b/api/v1beta1/novacompute_types.go index 2c73d26d9..35dca21bd 100644 --- a/api/v1beta1/novacompute_types.go +++ b/api/v1beta1/novacompute_types.go @@ -197,8 +197,8 @@ func (n NovaCompute) GetSecret() string { } // IsReady returns true if the Cell reconciled successfully -func (instance NovaCompute) IsReady() bool { - return instance.Status.Conditions.IsTrue(condition.ReadyCondition) +func (n NovaCompute) IsReady() bool { + return n.Status.Conditions.IsTrue(condition.ReadyCondition) } // NewNovaComputeSpec constructs a NewNovaComputeSpec @@ -240,16 +240,16 @@ func NewNovaComputeSpec( } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaCompute) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaCompute) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaCompute) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaCompute) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaCompute) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaCompute) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novacompute_webhook.go b/api/v1beta1/novacompute_webhook.go index 73db93d58..c3d06916a 100644 --- a/api/v1beta1/novacompute_webhook.go +++ b/api/v1beta1/novacompute_webhook.go @@ -31,7 +31,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -54,15 +53,6 @@ func SetupNovaComputeDefaults(defaults NovaComputeDefaults) { novacomputelog.Info("NovaCompute defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaCompute) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novacompute,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacomputes,verbs=create;update,versions=v1beta1,name=mnovacompute.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaCompute{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -79,9 +69,6 @@ func (spec *NovaComputeSpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novacompute,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacomputes,verbs=create;update,versions=v1beta1,name=vnovacompute.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaCompute{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type @@ -121,12 +108,14 @@ func (r *NovaCompute) ValidateUpdate(old runtime.Object) (admission.Warnings, er return nil, nil } -func (r *NovaComputeSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { - return r.validate(basePath, namespace) +// ValidateCreate validates the NovaComputeSpec during the webhook invocation +func (spec *NovaComputeSpec) ValidateCreate(basePath *field.Path, namespace string) field.ErrorList { + return spec.validate(basePath, namespace) } -func (r *NovaComputeSpec) ValidateUpdate(old NovaComputeSpec, basePath *field.Path, namespace string) field.ErrorList { - return r.validate(basePath, namespace) +// ValidateUpdate validates the NovaComputeSpec during the webhook invocation +func (spec *NovaComputeSpec) ValidateUpdate(old NovaComputeSpec, basePath *field.Path, namespace string) field.ErrorList { + return spec.validate(basePath, namespace) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type @@ -137,28 +126,28 @@ func (r *NovaCompute) ValidateDelete() (admission.Warnings, error) { return nil, nil } -func (r *NovaComputeSpec) validate(basePath *field.Path, namespace string) field.ErrorList { +func (spec *NovaComputeSpec) validate(basePath *field.Path, namespace string) field.ErrorList { var errors field.ErrorList - if r.ComputeDriver == IronicDriver && *r.NovaServiceBase.Replicas > 1 { + if spec.ComputeDriver == IronicDriver && *spec.NovaServiceBase.Replicas > 1 { errors = append( errors, field.Invalid( - basePath.Child("replicas"), *r.NovaServiceBase.Replicas, "should be max 1 for ironic.IronicDriver"), + basePath.Child("replicas"), *spec.NovaServiceBase.Replicas, "should be max 1 for ironic.IronicDriver"), ) } errors = append( errors, ValidateComputeDefaultConfigOverwrite( - basePath.Child("defaultConfigOverwrite"), r.DefaultConfigOverwrite)...) + basePath.Child("defaultConfigOverwrite"), spec.DefaultConfigOverwrite)...) errors = append(errors, topologyv1.ValidateTopologyRef( - r.TopologyRef, *basePath.Child("topologyRef"), namespace)...) + spec.TopologyRef, *basePath.Child("topologyRef"), namespace)...) return errors } -// ValidateReplicas validates replicas depend on compute driver +// ValidateIronicDriverReplicas validates replicas depend on compute driver func (r *NovaComputeTemplate) ValidateIronicDriverReplicas(basePath *field.Path) field.ErrorList { var errors field.ErrorList if *r.Replicas > 1 { @@ -171,11 +160,13 @@ func (r *NovaComputeTemplate) ValidateIronicDriverReplicas(basePath *field.Path) return errors } +// ValidateDefaultConfigOverwrite validates the defaultConfigOverwrite for NovaComputeTemplate func (r *NovaComputeTemplate) ValidateDefaultConfigOverwrite(basePath *field.Path) field.ErrorList { return ValidateComputeDefaultConfigOverwrite( basePath.Child("defaultConfigOverwrite"), r.DefaultConfigOverwrite) } +// ValidateComputeDefaultConfigOverwrite validates the defaultConfigOverwrite for NovaCompute func ValidateComputeDefaultConfigOverwrite( basePath *field.Path, defaultConfigOverwrite map[string]string, diff --git a/api/v1beta1/novaconductor_types.go b/api/v1beta1/novaconductor_types.go index 868d32cdb..9135b7ab8 100644 --- a/api/v1beta1/novaconductor_types.go +++ b/api/v1beta1/novaconductor_types.go @@ -248,7 +248,7 @@ func (n NovaConductor) GetKeystoneAuthURL() string { return n.Spec.KeystoneAuthURL } -// GetServiceUser returns the Service user from the Spec +// GetKeystoneUser returns the Service user from the Spec func (n NovaConductor) GetKeystoneUser() string { return n.Spec.ServiceUser } @@ -259,16 +259,16 @@ func (n NovaConductor) GetCABundleSecretName() string { } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaConductor) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaConductor) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaConductor) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaConductor) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaConductor) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaConductor) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novaconductor_webhook.go b/api/v1beta1/novaconductor_webhook.go index a8b512c04..26c23e9a8 100644 --- a/api/v1beta1/novaconductor_webhook.go +++ b/api/v1beta1/novaconductor_webhook.go @@ -30,7 +30,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -53,15 +52,6 @@ func SetupNovaConductorDefaults(defaults NovaConductorDefaults) { novaconductorlog.Info("NovaConductor defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaConductor) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novaconductor,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaconductors,verbs=create;update,versions=v1beta1,name=mnovaconductor.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaConductor{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -78,9 +68,6 @@ func (spec *NovaConductorSpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novaconductor,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaconductors,verbs=create;update,versions=v1beta1,name=vnovaconductor.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaConductor{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type diff --git a/api/v1beta1/novametadata_types.go b/api/v1beta1/novametadata_types.go index 192168c83..1594e9043 100644 --- a/api/v1beta1/novametadata_types.go +++ b/api/v1beta1/novametadata_types.go @@ -300,16 +300,16 @@ func (n NovaMetadata) GetSecret() string { } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaMetadata) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaMetadata) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaMetadata) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaMetadata) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaMetadata) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaMetadata) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novametadata_webhook.go b/api/v1beta1/novametadata_webhook.go index f243031bd..de0f1cfb3 100644 --- a/api/v1beta1/novametadata_webhook.go +++ b/api/v1beta1/novametadata_webhook.go @@ -30,7 +30,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -53,15 +52,6 @@ func SetupNovaMetadataDefaults(defaults NovaMetadataDefaults) { novametadatalog.Info("NovaMetadata defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaMetadata) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novametadata,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novametadata,verbs=create;update,versions=v1beta1,name=mnovametadata.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaMetadata{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -78,9 +68,6 @@ func (spec *NovaMetadataSpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novametadata,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novametadata,verbs=create;update,versions=v1beta1,name=vnovametadata.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaMetadata{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type @@ -156,12 +143,14 @@ func (r *NovaMetadataTemplate) ValidateCell0(basePath *field.Path) field.ErrorLi return errors } +// ValidateDefaultConfigOverwrite validates the defaultConfigOverwrite for NovaMetadataTemplate func (r *NovaMetadataTemplate) ValidateDefaultConfigOverwrite(basePath *field.Path) field.ErrorList { return ValidateMetadataDefaultConfigOverwrite( basePath.Child("defaultConfigOverwrite"), r.DefaultConfigOverwrite) } +// ValidateMetadataDefaultConfigOverwrite validates the defaultConfigOverwrite for NovaMetadata func ValidateMetadataDefaultConfigOverwrite( basePath *field.Path, defaultConfigOverwrite map[string]string, diff --git a/api/v1beta1/novanovncproxy_types.go b/api/v1beta1/novanovncproxy_types.go index 6bf46f1bc..b9e6c7ef0 100644 --- a/api/v1beta1/novanovncproxy_types.go +++ b/api/v1beta1/novanovncproxy_types.go @@ -271,16 +271,16 @@ func (n NovaNoVNCProxy) GetSecret() string { } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaNoVNCProxy) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaNoVNCProxy) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaNoVNCProxy) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaNoVNCProxy) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaNoVNCProxy) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaNoVNCProxy) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novanovncproxy_webhook.go b/api/v1beta1/novanovncproxy_webhook.go index 8a323b9dc..6d9ea0090 100644 --- a/api/v1beta1/novanovncproxy_webhook.go +++ b/api/v1beta1/novanovncproxy_webhook.go @@ -29,7 +29,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "k8s.io/apimachinery/pkg/runtime/schema" @@ -53,15 +52,6 @@ func SetupNovaNoVNCProxyDefaults(defaults NovaNoVNCProxyDefaults) { novanovncproxylog.Info("NovaNoVNCProxy defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaNoVNCProxy) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novanovncproxy,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novanovncproxies,verbs=create;update,versions=v1beta1,name=mnovanovncproxy.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaNoVNCProxy{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -78,9 +68,6 @@ func (spec *NovaNoVNCProxySpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novanovncproxy,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novanovncproxies,verbs=create;update,versions=v1beta1,name=vnovanovncproxy.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaNoVNCProxy{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type diff --git a/api/v1beta1/novascheduler_types.go b/api/v1beta1/novascheduler_types.go index 4f33dee96..d12971b00 100644 --- a/api/v1beta1/novascheduler_types.go +++ b/api/v1beta1/novascheduler_types.go @@ -198,7 +198,7 @@ func (n NovaScheduler) GetKeystoneAuthURL() string { return n.Spec.KeystoneAuthURL } -// GetServiceUser returns the Service user from the Spec +// GetKeystoneUser returns the Service user from the Spec func (n NovaScheduler) GetKeystoneUser() string { return n.Spec.ServiceUser } @@ -209,16 +209,16 @@ func (n NovaScheduler) GetCABundleSecretName() string { } // GetSpecTopologyRef - Returns the LastAppliedTopology Set in the Status -func (instance *NovaScheduler) GetSpecTopologyRef() *topologyv1.TopoRef { - return instance.Spec.TopologyRef +func (n *NovaScheduler) GetSpecTopologyRef() *topologyv1.TopoRef { + return n.Spec.TopologyRef } // GetLastAppliedTopology - Returns the LastAppliedTopology Set in the Status -func (instance *NovaScheduler) GetLastAppliedTopology() *topologyv1.TopoRef { - return instance.Status.LastAppliedTopology +func (n *NovaScheduler) GetLastAppliedTopology() *topologyv1.TopoRef { + return n.Status.LastAppliedTopology } // SetLastAppliedTopology - Sets the LastAppliedTopology value in the Status -func (instance *NovaScheduler) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { - instance.Status.LastAppliedTopology = topologyRef +func (n *NovaScheduler) SetLastAppliedTopology(topologyRef *topologyv1.TopoRef) { + n.Status.LastAppliedTopology = topologyRef } diff --git a/api/v1beta1/novascheduler_webhook.go b/api/v1beta1/novascheduler_webhook.go index d4748de5e..febb47dde 100644 --- a/api/v1beta1/novascheduler_webhook.go +++ b/api/v1beta1/novascheduler_webhook.go @@ -28,7 +28,6 @@ import ( "github.com/google/go-cmp/cmp" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" @@ -53,15 +52,6 @@ func SetupNovaSchedulerDefaults(defaults NovaSchedulerDefaults) { novaschedulerlog.Info("NovaScheduler defaults initialized", "defaults", defaults) } -// SetupWebhookWithManager sets up the webhook with the Manager -func (r *NovaScheduler) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -//+kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novascheduler,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaschedulers,verbs=create;update,versions=v1beta1,name=mnovascheduler.kb.io,admissionReviewVersions=v1 - var _ webhook.Defaulter = &NovaScheduler{} // Default implements webhook.Defaulter so a webhook will be registered for the type @@ -78,9 +68,6 @@ func (spec *NovaSchedulerSpec) Default() { } } -// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novascheduler,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaschedulers,verbs=create;update,versions=v1beta1,name=vnovascheduler.kb.io,admissionReviewVersions=v1 - var _ webhook.Validator = &NovaScheduler{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 000000000..e03113a59 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,331 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package main is the entry point for the nova-operator +package main + +import ( + "crypto/tls" + "flag" + "os" + "path/filepath" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/openstack-k8s-operators/nova-operator/internal/controller" + webhookv1beta1 "github.com/openstack-k8s-operators/nova-operator/internal/webhook/v1beta1" + // +kubebuilder:scaffold:imports + networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" + rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" + topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" + "github.com/openstack-k8s-operators/lib-common/modules/common/operator" + mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" + novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/controller-runtime/pkg/client/config" +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(novav1.AddToScheme(scheme)) + utilruntime.Must(mariadbv1.AddToScheme(scheme)) + utilruntime.Must(keystonev1.AddToScheme(scheme)) + utilruntime.Must(corev1.AddToScheme(scheme)) + utilruntime.Must(appsv1.AddToScheme(scheme)) + utilruntime.Must(rabbitmqv1.AddToScheme(scheme)) + utilruntime.Must(networkv1.AddToScheme(scheme)) + utilruntime.Must(memcachedv1.AddToScheme(scheme)) + utilruntime.Must(topologyv1.AddToScheme(scheme)) + //+kubebuilder:scaffold:scheme +} + +// nolint:gocyclo +func main() { + var metricsAddr string + var metricsCertPath, metricsCertName, metricsCertKey string + var webhookCertPath, webhookCertName, webhookCertKey string + var enableLeaderElection bool + var probeAddr string + var secureMetrics bool + var enableHTTP2 bool + var tlsOpts []func(*tls.Config) + flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ + "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&secureMetrics, "metrics-secure", true, + "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") + flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.") + flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.") + flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.") + flag.StringVar(&metricsCertPath, "metrics-cert-path", "", + "The directory that contains the metrics server certificate.") + flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.") + flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.") + flag.BoolVar(&enableHTTP2, "enable-http2", false, + "If set, HTTP/2 will be enabled for the metrics and webhook servers") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + // if the enable-http2 flag is false (the default), http/2 should be disabled + // due to its vulnerabilities. More specifically, disabling http/2 will + // prevent from being vulnerable to the HTTP/2 Stream Cancellation and + // Rapid Reset CVEs. For more information see: + // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 + // - https://github.com/advisories/GHSA-4374-p667-p6c8 + disableHTTP2 := func(c *tls.Config) { + setupLog.Info("disabling http/2") + c.NextProtos = []string{"http/1.1"} + } + + if !enableHTTP2 { + tlsOpts = append(tlsOpts, disableHTTP2) + } + + // Create watchers for metrics and webhooks certificates + var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher + + // Initial webhook TLS options + webhookTLSOpts := tlsOpts + + if len(webhookCertPath) > 0 { + setupLog.Info("Initializing webhook certificate watcher using provided certificates", + "webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey) + + var err error + webhookCertWatcher, err = certwatcher.New( + filepath.Join(webhookCertPath, webhookCertName), + filepath.Join(webhookCertPath, webhookCertKey), + ) + if err != nil { + setupLog.Error(err, "Failed to initialize webhook certificate watcher") + os.Exit(1) + } + + webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) { + config.GetCertificate = webhookCertWatcher.GetCertificate + }) + } + + webhookServer := webhook.NewServer(webhook.Options{ + TLSOpts: webhookTLSOpts, + }) + + // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. + // More info: + // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server + // - https://book.kubebuilder.io/reference/metrics.html + metricsServerOptions := metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + TLSOpts: tlsOpts, + } + + if secureMetrics { + // FilterProvider is used to protect the metrics endpoint with authn/authz. + // These configurations ensure that only authorized users and service accounts + // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: + // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization + } + + // If the certificate is not specified, controller-runtime will automatically + // generate self-signed certificates for the metrics server. While convenient for development and testing, + // this setup is not recommended for production. + // + // TODO(user): If you enable certManager, uncomment the following lines: + // - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates + // managed by cert-manager for the metrics server. + // - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification. + if len(metricsCertPath) > 0 { + setupLog.Info("Initializing metrics certificate watcher using provided certificates", + "metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey) + + var err error + metricsCertWatcher, err = certwatcher.New( + filepath.Join(metricsCertPath, metricsCertName), + filepath.Join(metricsCertPath, metricsCertKey), + ) + if err != nil { + setupLog.Error(err, "to initialize metrics certificate watcher", "error", err) + os.Exit(1) + } + + metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) { + config.GetCertificate = metricsCertWatcher.GetCertificate + }) + } + + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader don't have to wait + // LeaseDuration time first. + // + // In the default scaffold provided, the program ends immediately after + // the manager stops, so would be fine to enable this option. However, + // if you are doing or is intended to do any operation such as perform cleanups + // after the manager stops then its usage might be unsafe. + // LeaderElectionReleaseOnCancel: true, + options := ctrl.Options{ + Scheme: scheme, + Metrics: metricsServerOptions, + WebhookServer: webhookServer, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "f33036c1.openstack.org", + } + + // apply common openstack operator manager options + err := operator.SetManagerOptions(&options, setupLog) + if err != nil { + setupLog.Error(err, "unable to set manager options") + os.Exit(1) + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + cfg, err := config.GetConfig() + if err != nil { + setupLog.Error(err, "unable to get config") + os.Exit(1) + } + + kclient, err := kubernetes.NewForConfig(cfg) + if err != nil { + setupLog.Error(err, "unable to create k8s client") + os.Exit(1) + } + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + reconcilers := controller.NewReconcilers(mgr, kclient) + err = reconcilers.Setup(mgr, setupLog) + if err != nil { + os.Exit(1) + } + + // Acquire environmental defaults and initialize operator defaults with them + novav1.SetupDefaults() + + // nolint:goconst + checker := healthz.Ping + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err := webhookv1beta1.SetupNovaAPIWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaAPI") + os.Exit(1) + } + + if err := webhookv1beta1.SetupNovaSchedulerWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaScheduler") + os.Exit(1) + } + + if err := webhookv1beta1.SetupNovaConductorWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaConductor") + os.Exit(1) + } + if err := webhookv1beta1.SetupNovaMetadataWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaMetadata") + os.Exit(1) + } + if err := webhookv1beta1.SetupNovaNoVNCProxyWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaNoVNCProxy") + os.Exit(1) + } + if err := webhookv1beta1.SetupNovaCellWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaCell") + os.Exit(1) + } + if err := webhookv1beta1.SetupNovaWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Nova") + os.Exit(1) + } + if err := webhookv1beta1.SetupNovaComputeWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "NovaCompute") + os.Exit(1) + } + checker = mgr.GetWebhookServer().StartedChecker() + + } + // +kubebuilder:scaffold:builder + + if metricsCertWatcher != nil { + setupLog.Info("Adding metrics certificate watcher to manager") + if err := mgr.Add(metricsCertWatcher); err != nil { + setupLog.Error(err, "unable to add metrics certificate watcher to manager") + os.Exit(1) + } + } + + if webhookCertWatcher != nil { + setupLog.Info("Adding webhook certificate watcher to manager") + if err := mgr.Add(webhookCertWatcher); err != nil { + setupLog.Error(err, "unable to add webhook certificate watcher to manager") + os.Exit(1) + } + } + + if err := mgr.AddHealthzCheck("healthz", checker); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", checker); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/config/certmanager/certificate-metrics.yaml b/config/certmanager/certificate-metrics.yaml new file mode 100644 index 000000000..d2afbe80f --- /dev/null +++ b/config/certmanager/certificate-metrics.yaml @@ -0,0 +1,20 @@ +# The following manifests contain a self-signed issuer CR and a metrics certificate CR. +# More document can be found at https://docs.cert-manager.io +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + dnsNames: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + # replacements in the config/default/kustomization.yaml file. + - SERVICE_NAME.SERVICE_NAMESPACE.svc + - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: metrics-server-cert diff --git a/config/certmanager/certificate-webhook.yaml b/config/certmanager/certificate-webhook.yaml new file mode 100644 index 000000000..70cf63504 --- /dev/null +++ b/config/certmanager/certificate-webhook.yaml @@ -0,0 +1,20 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + # replacements in the config/default/kustomization.yaml file. + dnsNames: + - SERVICE_NAME.SERVICE_NAMESPACE.svc + - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml deleted file mode 100644 index 17e9ada6d..000000000 --- a/config/certmanager/certificate.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - app.kubernetes.io/name: issuer - app.kubernetes.io/instance: selfsigned-issuer - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: nova-operator - app.kubernetes.io/part-of: nova-operator - app.kubernetes.io/managed-by: kustomize - name: selfsigned-issuer - namespace: system -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: certificate - app.kubernetes.io/instance: serving-cert - app.kubernetes.io/component: certificate - app.kubernetes.io/created-by: nova-operator - app.kubernetes.io/part-of: nova-operator - app.kubernetes.io/managed-by: kustomize - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: system -spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize - dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/issuer.yaml b/config/certmanager/issuer.yaml new file mode 100644 index 000000000..af8457a18 --- /dev/null +++ b/config/certmanager/issuer.yaml @@ -0,0 +1,13 @@ +# The following manifest contains a self-signed issuer CR. +# More information can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml index bebea5a59..fcb7498e4 100644 --- a/config/certmanager/kustomization.yaml +++ b/config/certmanager/kustomization.yaml @@ -1,5 +1,7 @@ resources: -- certificate.yaml +- issuer.yaml +- certificate-webhook.yaml +- certificate-metrics.yaml configurations: - kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml index e631f7773..cf6f89e88 100644 --- a/config/certmanager/kustomizeconfig.yaml +++ b/config/certmanager/kustomizeconfig.yaml @@ -1,4 +1,4 @@ -# This configuration is for teaching kustomize how to update name ref and var substitution +# This configuration is for teaching kustomize how to update name ref substitution nameReference: - kind: Issuer group: cert-manager.io @@ -6,11 +6,3 @@ nameReference: - kind: Certificate group: cert-manager.io path: spec/issuerRef/name - -varReference: -- kind: Certificate - group: cert-manager.io - path: spec/commonName -- kind: Certificate - group: cert-manager.io - path: spec/dnsNames diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 3541ef6b4..6c51197bd 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -10,31 +10,14 @@ resources: - bases/nova.openstack.org_novacells.yaml - bases/nova.openstack.org_nova.yaml - bases/nova.openstack.org_novacomputes.yaml -#+kubebuilder:scaffold:crdkustomizeresource +# +kubebuilder:scaffold:crdkustomizeresource patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- path: patches/webhook_in_novaapis.yaml -#- path: patches/webhook_in_novaschedulers.yaml -#- path: patches/webhook_in_novaconductors.yaml -#- path: patches/webhook_in_novametadata.yaml -#- path: patches/webhook_in_novanovncproxies.yaml -#- path: patches/webhook_in_novacells.yaml -#- path: patches/webhook_in_nova.yaml -#+kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- path: patches/cainjection_in_novaapis.yaml -#- path: patches/cainjection_in_novaschedulers.yaml -#- path: patches/cainjection_in_novaconductors.yaml -#- path: patches/cainjection_in_novametadata.yaml -#- path: patches/cainjection_in_novanovncproxies.yaml -#- path: patches/cainjection_in_novacells.yaml -#- path: patches/cainjection_in_nova.yaml -#+kubebuilder:scaffold:crdkustomizecainjectionpatch +# +kubebuilder:scaffold:crdkustomizewebhookpatch +# [WEBHOOK] To enable webhook, uncomment the following section # the following config is for teaching kustomize how to do kustomization for CRDs. -configurations: -- kustomizeconfig.yaml +#configurations: +#- kustomizeconfig.yaml diff --git a/config/crd/patches/cainjection_in_nova.yaml b/config/crd/patches/cainjection_in_nova.yaml deleted file mode 100644 index 1082abb5d..000000000 --- a/config/crd/patches/cainjection_in_nova.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: nova.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novaapis.yaml b/config/crd/patches/cainjection_in_novaapis.yaml deleted file mode 100644 index 9db9dfbb7..000000000 --- a/config/crd/patches/cainjection_in_novaapis.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novaapis.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novacells.yaml b/config/crd/patches/cainjection_in_novacells.yaml deleted file mode 100644 index a90ee012d..000000000 --- a/config/crd/patches/cainjection_in_novacells.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novacells.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novacomputes.yaml b/config/crd/patches/cainjection_in_novacomputes.yaml deleted file mode 100644 index d8de897b7..000000000 --- a/config/crd/patches/cainjection_in_novacomputes.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novacomputes.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novaconductors.yaml b/config/crd/patches/cainjection_in_novaconductors.yaml deleted file mode 100644 index 0f568d2d4..000000000 --- a/config/crd/patches/cainjection_in_novaconductors.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novaconductors.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novametadata.yaml b/config/crd/patches/cainjection_in_novametadata.yaml deleted file mode 100644 index cd4c30156..000000000 --- a/config/crd/patches/cainjection_in_novametadata.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novametadata.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novanovncproxies.yaml b/config/crd/patches/cainjection_in_novanovncproxies.yaml deleted file mode 100644 index e96b97637..000000000 --- a/config/crd/patches/cainjection_in_novanovncproxies.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novanovncproxies.nova.openstack.org diff --git a/config/crd/patches/cainjection_in_novaschedulers.yaml b/config/crd/patches/cainjection_in_novaschedulers.yaml deleted file mode 100644 index e9dc78a99..000000000 --- a/config/crd/patches/cainjection_in_novaschedulers.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: novaschedulers.nova.openstack.org diff --git a/config/crd/patches/webhook_in_nova.yaml b/config/crd/patches/webhook_in_nova.yaml deleted file mode 100644 index c5afc77aa..000000000 --- a/config/crd/patches/webhook_in_nova.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: nova.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novaapis.yaml b/config/crd/patches/webhook_in_novaapis.yaml deleted file mode 100644 index 676de8e15..000000000 --- a/config/crd/patches/webhook_in_novaapis.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novaapis.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novacells.yaml b/config/crd/patches/webhook_in_novacells.yaml deleted file mode 100644 index 12f48a126..000000000 --- a/config/crd/patches/webhook_in_novacells.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novacells.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novacomputes.yaml b/config/crd/patches/webhook_in_novacomputes.yaml deleted file mode 100644 index 6b636d4ad..000000000 --- a/config/crd/patches/webhook_in_novacomputes.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novacomputes.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novaconductors.yaml b/config/crd/patches/webhook_in_novaconductors.yaml deleted file mode 100644 index f18deb024..000000000 --- a/config/crd/patches/webhook_in_novaconductors.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novaconductors.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novametadata.yaml b/config/crd/patches/webhook_in_novametadata.yaml deleted file mode 100644 index 32cfa5a39..000000000 --- a/config/crd/patches/webhook_in_novametadata.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novametadata.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novanovncproxies.yaml b/config/crd/patches/webhook_in_novanovncproxies.yaml deleted file mode 100644 index 8ebf4f40b..000000000 --- a/config/crd/patches/webhook_in_novanovncproxies.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novanovncproxies.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/crd/patches/webhook_in_novaschedulers.yaml b/config/crd/patches/webhook_in_novaschedulers.yaml deleted file mode 100644 index fdaa75f48..000000000 --- a/config/crd/patches/webhook_in_novaschedulers.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# The following patch enables a conversion webhook for the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: novaschedulers.nova.openstack.org -spec: - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: system - name: webhook-service - path: /convert - conversionReviewVersions: - - v1 diff --git a/config/default/cert_metrics_manager_patch.yaml b/config/default/cert_metrics_manager_patch.yaml new file mode 100644 index 000000000..d97501553 --- /dev/null +++ b/config/default/cert_metrics_manager_patch.yaml @@ -0,0 +1,30 @@ +# This patch adds the args, volumes, and ports to allow the manager to use the metrics-server certs. + +# Add the volumeMount for the metrics-server certs +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: + mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + +# Add the --metrics-cert-path argument for the metrics server +- op: add + path: /spec/template/spec/containers/0/args/- + value: --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs + +# Add the metrics-server certs volume configuration +- op: add + path: /spec/template/spec/volumes/- + value: + name: metrics-certs + secret: + secretName: metrics-server-cert + optional: false + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 4e8c71176..8a5c75f87 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -9,8 +9,10 @@ namespace: nova-operator-system namePrefix: nova-operator- # Labels to add to all resources and selectors. -#commonLabels: -# someName: someValue +#labels: +#- includeSelectors: true +# pairs: +# someName: someValue resources: - ../crd @@ -20,58 +22,215 @@ resources: # crd/kustomization.yaml - ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager +- ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus +# [METRICS] Expose the controller manager metrics service. +- metrics_service.yaml +# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. +# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. +# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will +# be able to communicate with the Webhook Server. +#- ../network-policy +# Uncomment the patches line if you enable Metrics patches: -# Protect the /metrics endpoint by putting it behind auth. -# If you want your controller-manager to expose the /metrics -# endpoint w/o any authn/z, please comment the following line. -- path: manager_auth_proxy_patch.yaml +# Injects our custom images (ENV variable settings) +- path: manager_default_images.yaml +# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. +# More info: https://book.kubebuilder.io/reference/metrics +- path: manager_metrics_patch.yaml + target: + kind: Deployment -# Mount the controller config file for loading manager configurations -# through a ComponentConfig type -#- path: manager_config_patch.yaml +# Uncomment the patches line if you enable Metrics and CertManager +# [METRICS-WITH-CERTS] To enable metrics protected with certManager, uncomment the following line. +# This patch will protect the metrics with certManager self-signed certs. +- path: cert_metrics_manager_patch.yaml + target: + kind: Deployment # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml - path: manager_webhook_patch.yaml + target: + kind: Deployment -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- path: webhookcainjection_patch.yaml - -# Injects our custom images (ENV variable settings) -- path: manager_default_images.yaml - -# the following config is for teaching kustomize how to do var substitution -vars: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service +# Uncomment the following replacements to add the cert-manager CA injection annotations +#replacements: +# - source: # Uncomment the following block to enable certificates for metrics +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.name +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - select: # Uncomment the following to set the Service name for TLS config in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 0 +# create: true +# +# - source: +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.namespace +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# - select: # Uncomment the following to set the Service namespace for TLS in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have any webhook +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.name # Name of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - source: +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.namespace # Namespace of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionns +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert +# fieldPath: .metadata.name +# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD. +# +kubebuilder:scaffold:crdkustomizecainjectionname diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml deleted file mode 100644 index c5e2b76e6..000000000 --- a/config/default/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: quay.io/openstack-k8s-operators/kube-rbac-proxy:v0.16.0 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/default/manager_config_patch.yaml b/config/default/manager_config_patch.yaml deleted file mode 100644 index 6c400155c..000000000 --- a/config/default/manager_config_patch.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - args: - - "--config=controller_manager_config.yaml" - volumeMounts: - - name: manager-config - mountPath: /controller_manager_config.yaml - subPath: controller_manager_config.yaml - volumes: - - name: manager-config - configMap: - name: manager-config diff --git a/config/default/manager_metrics_patch.yaml b/config/default/manager_metrics_patch.yaml new file mode 100644 index 000000000..2aaef6536 --- /dev/null +++ b/config/default/manager_metrics_patch.yaml @@ -0,0 +1,4 @@ +# This patch adds the args to allow exposing the metrics endpoint using HTTPS +- op: add + path: /spec/template/spec/containers/0/args/0 + value: --metrics-bind-address=:8443 diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml index fef8a1c9e..963c8a4cc 100644 --- a/config/default/manager_webhook_patch.yaml +++ b/config/default/manager_webhook_patch.yaml @@ -1,23 +1,31 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - ports: - - containerPort: 9444 - name: webhook-server - protocol: TCP - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert +# This patch ensures the webhook certificates are properly mounted in the manager container. +# It configures the necessary arguments, volumes, volume mounts, and container ports. + +# Add the --webhook-cert-path argument for configuring the webhook certificate path +- op: add + path: /spec/template/spec/containers/0/args/- + value: --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + +# Add the volumeMount for the webhook certificates +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: + mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + +# Add the port configuration for the webhook server +- op: add + path: /spec/template/spec/containers/0/ports/- + value: + containerPort: 9443 + name: webhook-server + protocol: TCP + +# Add the volume configuration for the webhook certificates +- op: add + path: /spec/template/spec/volumes/- + value: + name: webhook-certs + secret: + secretName: webhook-server-cert diff --git a/config/default/metrics_service.yaml b/config/default/metrics_service.yaml new file mode 100644 index 000000000..e2d9625cc --- /dev/null +++ b/config/default/metrics_service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: controller-manager + app.kubernetes.io/name: nova-operator diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml deleted file mode 100644 index 3b775ab02..000000000 --- a/config/default/webhookcainjection_patch.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: mutatingwebhookconfiguration - app.kubernetes.io/instance: mutating-webhook-configuration - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: nova-operator - app.kubernetes.io/part-of: nova-operator - app.kubernetes.io/managed-by: kustomize - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: validatingwebhookconfiguration - app.kubernetes.io/instance: validating-webhook-configuration - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: nova-operator - app.kubernetes.io/part-of: nova-operator - app.kubernetes.io/managed-by: kustomize - name: validating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manager/controller_manager_config.yaml b/config/manager/controller_manager_config.yaml deleted file mode 100644 index a92f8355f..000000000 --- a/config/manager/controller_manager_config.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 -kind: ControllerManagerConfig -health: - healthProbeBindAddress: :8081 -metrics: - bindAddress: 127.0.0.1:8080 -webhook: - port: 9444 -leaderElection: - leaderElect: true - resourceName: f33036c1.openstack.org -# leaderElectionReleaseOnCancel defines if the leader should step down volume -# when the Manager ends. This requires the binary to immediately end when the -# Manager is stopped, otherwise, this setting is unsafe. Setting this significantly -# speeds up voluntary leader transitions as the new leader don't have to wait -# LeaseDuration time first. -# In the default scaffold provided, the program ends immediately after -# the manager stops, so would be fine to enable this option. However, -# if you are doing or is intended to do any operation such as perform cleanups -# after the manager stops then its usage might be unsafe. -# leaderElectionReleaseOnCancel: true diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 7122857f8..8f9a84bd0 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,13 +1,5 @@ resources: - manager.yaml - -generatorOptions: - disableNameSuffixHash: true - -configMapGenerator: -- files: - - controller_manager_config.yaml - name: manager-config apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index a628d85b2..a57345282 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -3,6 +3,8 @@ kind: Namespace metadata: labels: control-plane: controller-manager + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: system --- apiVersion: apps/v1 @@ -12,11 +14,13 @@ metadata: namespace: system labels: control-plane: controller-manager - openstack.org/operator-name: nova + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize spec: selector: matchLabels: - openstack.org/operator-name: nova + control-plane: controller-manager + app.kubernetes.io/name: nova-operator replicas: 1 template: metadata: @@ -24,29 +28,49 @@ spec: kubectl.kubernetes.io/default-container: manager labels: control-plane: controller-manager - openstack.org/operator-name: nova + app.kubernetes.io/name: nova-operator spec: + # TODO(user): Uncomment the following code to configure the nodeAffinity expression + # according to the platforms which are supported by your solution. + # It is considered best practice to support multiple architectures. You can + # build your manager image using the makefile target docker-buildx. + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/arch + # operator: In + # values: + # - amd64 + # - arm64 + # - ppc64le + # - s390x + # - key: kubernetes.io/os + # operator: In + # values: + # - linux securityContext: + # Projects are configured by default to adhere to the "restricted" Pod Security Standards. + # This ensures that deployments meet the highest security requirements for Kubernetes. + # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted runAsNonRoot: true - # TODO(user): For common cases that do not require escalating privileges - # it is recommended to ensure that all your Pods/Containers are restrictive. - # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - # Please uncomment the following code if your project does NOT have to work on old Kubernetes - # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). - # seccompProfile: - # type: RuntimeDefault + seccompProfile: + type: RuntimeDefault containers: - command: - /manager args: - - --leader-elect + - --leader-elect + - --health-probe-bind-address=:8081 image: controller:latest name: manager + ports: [] securityContext: allowPrivilegeEscalation: false capabilities: drop: - - "ALL" + - "ALL" livenessProbe: httpGet: path: /healthz @@ -64,9 +88,11 @@ spec: resources: limits: cpu: 500m - memory: 256Mi + memory: 128Mi requests: cpu: 10m - memory: 128Mi + memory: 64Mi + volumeMounts: [] + volumes: [] serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/nova-operator.clusterserviceversion.yaml b/config/manifests/bases/nova-operator.clusterserviceversion.yaml index 49d5abebb..40c6cbde8 100644 --- a/config/manifests/bases/nova-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/nova-operator.clusterserviceversion.yaml @@ -42,11 +42,11 @@ spec: - description: Service - Cert secret used for the nova novnc service endpoint displayName: Service path: noVNCProxyServiceTemplate.tls.service - - description: Vencrypt - cert secret containing the x509 certificate to be - presented to the VNC server. The CommonName field should match the primary - hostname of the controller node. If using a HA deployment, the Organization - field can also be configured to a value that is common across all console - proxy instances in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration + - description: |- + Vencrypt - cert secret containing the x509 certificate to be presented to the VNC server. + The CommonName field should match the primary hostname of the controller node. If using a HA deployment, + the Organization field can also be configured to a value that is common across all console proxy instances in the deployment. + https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration displayName: Vencrypt path: noVNCProxyServiceTemplate.tls.vencrypt - description: TLS - Parameters related to the TLS @@ -91,11 +91,11 @@ spec: - description: Service - Cert secret used for the nova novnc service endpoint displayName: Service path: tls.service - - description: Vencrypt - cert secret containing the x509 certificate to be - presented to the VNC server. The CommonName field should match the primary - hostname of the controller node. If using a HA deployment, the Organization - field can also be configured to a value that is common across all console - proxy instances in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration + - description: |- + Vencrypt - cert secret containing the x509 certificate to be presented to the VNC server. + The CommonName field should match the primary hostname of the controller node. If using a HA deployment, + the Organization field can also be configured to a value that is common across all console proxy instances in the deployment. + https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration displayName: Vencrypt path: tls.vencrypt version: v1beta1 @@ -116,11 +116,11 @@ spec: - description: Service - Cert secret used for the nova novnc service endpoint displayName: Service path: cellTemplates.noVNCProxyServiceTemplate.tls.service - - description: Vencrypt - cert secret containing the x509 certificate to be - presented to the VNC server. The CommonName field should match the primary - hostname of the controller node. If using a HA deployment, the Organization - field can also be configured to a value that is common across all console - proxy instances in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration + - description: |- + Vencrypt - cert secret containing the x509 certificate to be presented to the VNC server. + The CommonName field should match the primary hostname of the controller node. If using a HA deployment, + the Organization field can also be configured to a value that is common across all console proxy instances in the deployment. + https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration displayName: Vencrypt path: cellTemplates.noVNCProxyServiceTemplate.tls.vencrypt - description: TLS - Parameters related to the TLS @@ -158,6 +158,7 @@ spec: - name: Nova Operator url: https://github.com/openstack-k8s-operators/nova-operator maturity: beta + minKubeVersion: 0.0.0 provider: name: Red Hat Inc. url: https://redhat.com/ diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 9dd490692..daba8050e 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -20,7 +20,8 @@ resources: # # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. # # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. # - op: remove -# path: /spec/template/spec/containers/1/volumeMounts/0 + +# path: /spec/template/spec/containers/0/volumeMounts/0 # # Remove the "cert" volume, since OLM will create and mount a set of certs. # # Update the indices in this path if adding or removing volumes in the manager's Deployment. # - op: remove diff --git a/config/network-policy/allow-metrics-traffic.yaml b/config/network-policy/allow-metrics-traffic.yaml new file mode 100644 index 000000000..6aaecf98b --- /dev/null +++ b/config/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,27 @@ +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gather data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: allow-metrics-traffic + namespace: system +spec: + podSelector: + matchLabels: + control-plane: controller-manager + app.kubernetes.io/name: nova-operator + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label metrics: enabled + - from: + - namespaceSelector: + matchLabels: + metrics: enabled # Only from namespaces with this label + ports: + - port: 8443 + protocol: TCP diff --git a/config/network-policy/allow-webhook-traffic.yaml b/config/network-policy/allow-webhook-traffic.yaml new file mode 100644 index 000000000..24671df9a --- /dev/null +++ b/config/network-policy/allow-webhook-traffic.yaml @@ -0,0 +1,27 @@ +# This NetworkPolicy allows ingress traffic to your webhook server running +# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks +# will only work when applied in namespaces labeled with 'webhook: enabled' +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: allow-webhook-traffic + namespace: system +spec: + podSelector: + matchLabels: + control-plane: controller-manager + app.kubernetes.io/name: nova-operator + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label webhook: enabled + - from: + - namespaceSelector: + matchLabels: + webhook: enabled # Only from namespaces with this label + ports: + - port: 443 + protocol: TCP diff --git a/config/network-policy/kustomization.yaml b/config/network-policy/kustomization.yaml new file mode 100644 index 000000000..0872bee12 --- /dev/null +++ b/config/network-policy/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- allow-webhook-traffic.yaml +- allow-metrics-traffic.yaml diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml index ed137168a..fdc5481b1 100644 --- a/config/prometheus/kustomization.yaml +++ b/config/prometheus/kustomization.yaml @@ -1,2 +1,11 @@ resources: - monitor.yaml + +# [PROMETHEUS-WITH-CERTS] The following patch configures the ServiceMonitor in ../prometheus +# to securely reference certificates created and managed by cert-manager. +# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml +# to mount the "metrics-server-cert" secret in the Manager Deployment. +#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml index af3641d23..2cbcdaedb 100644 --- a/config/prometheus/monitor.yaml +++ b/config/prometheus/monitor.yaml @@ -1,20 +1,27 @@ - # Prometheus Monitor Service (Metrics) apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: control-plane: controller-manager + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-monitor namespace: system spec: endpoints: - path: /metrics - port: https + port: https # Ensure this is the name of the port that exposes HTTPS metrics scheme: https bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token tlsConfig: + # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables + # certificate verification, exposing the system to potential man-in-the-middle attacks. + # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. + # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, + # which securely references the certificate from the 'metrics-server-cert' secret. insecureSkipVerify: true selector: matchLabels: - openstack.org/operator-name: nova + control-plane: controller-manager + app.kubernetes.io/name: nova-operator diff --git a/config/prometheus/monitor_tls_patch.yaml b/config/prometheus/monitor_tls_patch.yaml new file mode 100644 index 000000000..5bf84ce0d --- /dev/null +++ b/config/prometheus/monitor_tls_patch.yaml @@ -0,0 +1,19 @@ +# Patch for Prometheus ServiceMonitor to enable secure TLS configuration +# using certificates managed by cert-manager +- op: replace + path: /spec/endpoints/0/tlsConfig + value: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + serverName: SERVICE_NAME.SERVICE_NAMESPACE.svc + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml deleted file mode 100644 index 92b09d318..000000000 --- a/config/rbac/auth_proxy_service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - name: controller-manager-metrics-service - namespace: openstack -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - openstack.org/operator-name: nova diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 731832a6a..63d4c550c 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -9,10 +9,40 @@ resources: - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -# Comment the following 4 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml -- auth_proxy_client_clusterrole.yaml +# The following RBAC configurations are used to protect +# the metrics endpoint with authn/authz. These configurations +# ensure that only authorized users and service accounts +# can access the metrics endpoint. Comment the following +# permissions if you want to disable this protection. +# More info: https://book.kubebuilder.io/reference/metrics.html +- metrics_auth_role.yaml +- metrics_auth_role_binding.yaml +- metrics_reader_role.yaml +# For each CRD, "Admin", "Editor" and "Viewer" roles are scaffolded by +# default, aiding admins in cluster management. Those roles are +# not used by the nova-operator itself. You can comment the following lines +# if you do not want those helpers be installed with your Project. +- novacompute_admin_role.yaml +- novacompute_editor_role.yaml +- novacompute_viewer_role.yaml +- nova_admin_role.yaml +- nova_editor_role.yaml +- nova_viewer_role.yaml +- novacell_admin_role.yaml +- novacell_editor_role.yaml +- novacell_viewer_role.yaml +- novanovncproxy_admin_role.yaml +- novanovncproxy_editor_role.yaml +- novanovncproxy_viewer_role.yaml +- novametadata_admin_role.yaml +- novametadata_editor_role.yaml +- novametadata_viewer_role.yaml +- novaconductor_admin_role.yaml +- novaconductor_editor_role.yaml +- novaconductor_viewer_role.yaml +- novascheduler_admin_role.yaml +- novascheduler_editor_role.yaml +- novascheduler_viewer_role.yaml +- novaapi_admin_role.yaml +- novaapi_editor_role.yaml +- novaapi_viewer_role.yaml diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml index 4190ec805..e94078ed6 100644 --- a/config/rbac/leader_election_role.yaml +++ b/config/rbac/leader_election_role.yaml @@ -2,6 +2,9 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: leader-election-role rules: - apiGroups: diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml index 76a567cb9..dc862fd31 100644 --- a/config/rbac/leader_election_role_binding.yaml +++ b/config/rbac/leader_election_role_binding.yaml @@ -1,6 +1,9 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: leader-election-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io @@ -9,4 +12,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: openstack + namespace: system diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/metrics_auth_role.yaml similarity index 90% rename from config/rbac/auth_proxy_role.yaml rename to config/rbac/metrics_auth_role.yaml index 80e1857c5..32d2e4ec6 100644 --- a/config/rbac/auth_proxy_role.yaml +++ b/config/rbac/metrics_auth_role.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: proxy-role + name: metrics-auth-role rules: - apiGroups: - authentication.k8s.io diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/metrics_auth_role_binding.yaml similarity index 71% rename from config/rbac/auth_proxy_role_binding.yaml rename to config/rbac/metrics_auth_role_binding.yaml index de2738958..e775d67ff 100644 --- a/config/rbac/auth_proxy_role_binding.yaml +++ b/config/rbac/metrics_auth_role_binding.yaml @@ -1,12 +1,12 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: proxy-rolebinding + name: metrics-auth-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: proxy-role + name: metrics-auth-role subjects: - kind: ServiceAccount name: controller-manager - namespace: openstack + namespace: system diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/metrics_reader_role.yaml similarity index 100% rename from config/rbac/auth_proxy_client_clusterrole.yaml rename to config/rbac/metrics_reader_role.yaml diff --git a/config/rbac/nova_admin_role.yaml b/config/rbac/nova_admin_role.yaml new file mode 100644 index 000000000..7baa63668 --- /dev/null +++ b/config/rbac/nova_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: nova-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - nova + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - nova/status + verbs: + - get diff --git a/config/rbac/nova_editor_role.yaml b/config/rbac/nova_editor_role.yaml index a2ca2f8dc..edd18ad1f 100644 --- a/config/rbac/nova_editor_role.yaml +++ b/config/rbac/nova_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit nova. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: nova-editor-role rules: - apiGroups: diff --git a/config/rbac/nova_viewer_role.yaml b/config/rbac/nova_viewer_role.yaml index 1b53b7ddb..e3e1d9e11 100644 --- a/config/rbac/nova_viewer_role.yaml +++ b/config/rbac/nova_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view nova. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: nova-viewer-role rules: - apiGroups: diff --git a/config/rbac/novaapi_admin_role.yaml b/config/rbac/novaapi_admin_role.yaml new file mode 100644 index 000000000..09ef7467c --- /dev/null +++ b/config/rbac/novaapi_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novaapi-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novaapis + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novaapis/status + verbs: + - get diff --git a/config/rbac/novaapi_editor_role.yaml b/config/rbac/novaapi_editor_role.yaml index 0907161c5..ca874c875 100644 --- a/config/rbac/novaapi_editor_role.yaml +++ b/config/rbac/novaapi_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novaapis. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novaapi-editor-role rules: - apiGroups: diff --git a/config/rbac/novaapi_viewer_role.yaml b/config/rbac/novaapi_viewer_role.yaml index 4378741e3..4eab129f6 100644 --- a/config/rbac/novaapi_viewer_role.yaml +++ b/config/rbac/novaapi_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novaapis. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novaapi-viewer-role rules: - apiGroups: diff --git a/config/rbac/novacell_admin_role.yaml b/config/rbac/novacell_admin_role.yaml new file mode 100644 index 000000000..241bad777 --- /dev/null +++ b/config/rbac/novacell_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novacell-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novacells + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novacells/status + verbs: + - get diff --git a/config/rbac/novacell_editor_role.yaml b/config/rbac/novacell_editor_role.yaml index 0f0f90a4f..44da82da6 100644 --- a/config/rbac/novacell_editor_role.yaml +++ b/config/rbac/novacell_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novacells. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novacell-editor-role rules: - apiGroups: diff --git a/config/rbac/novacell_viewer_role.yaml b/config/rbac/novacell_viewer_role.yaml index c321200e7..0e32779d5 100644 --- a/config/rbac/novacell_viewer_role.yaml +++ b/config/rbac/novacell_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novacells. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novacell-viewer-role rules: - apiGroups: diff --git a/config/rbac/novacompute_admin_role.yaml b/config/rbac/novacompute_admin_role.yaml new file mode 100644 index 000000000..06545fab4 --- /dev/null +++ b/config/rbac/novacompute_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novacompute-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novacomputes + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novacomputes/status + verbs: + - get diff --git a/config/rbac/novacompute_editor_role.yaml b/config/rbac/novacompute_editor_role.yaml index d2bc35002..6618231a7 100644 --- a/config/rbac/novacompute_editor_role.yaml +++ b/config/rbac/novacompute_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novacomputes. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novacompute-editor-role rules: - apiGroups: diff --git a/config/rbac/novacompute_viewer_role.yaml b/config/rbac/novacompute_viewer_role.yaml index 54cded4d0..c07ea000e 100644 --- a/config/rbac/novacompute_viewer_role.yaml +++ b/config/rbac/novacompute_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novacomputes. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novacompute-viewer-role rules: - apiGroups: diff --git a/config/rbac/novaconductor_admin_role.yaml b/config/rbac/novaconductor_admin_role.yaml new file mode 100644 index 000000000..59c4e014d --- /dev/null +++ b/config/rbac/novaconductor_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novaconductor-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novaconductors + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novaconductors/status + verbs: + - get diff --git a/config/rbac/novaconductor_editor_role.yaml b/config/rbac/novaconductor_editor_role.yaml index 594bb106c..05959f60f 100644 --- a/config/rbac/novaconductor_editor_role.yaml +++ b/config/rbac/novaconductor_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novaconductors. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novaconductor-editor-role rules: - apiGroups: diff --git a/config/rbac/novaconductor_viewer_role.yaml b/config/rbac/novaconductor_viewer_role.yaml index b87a34ea6..af10ea712 100644 --- a/config/rbac/novaconductor_viewer_role.yaml +++ b/config/rbac/novaconductor_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novaconductors. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novaconductor-viewer-role rules: - apiGroups: diff --git a/config/rbac/novametadata_admin_role.yaml b/config/rbac/novametadata_admin_role.yaml new file mode 100644 index 000000000..6aff0ec3a --- /dev/null +++ b/config/rbac/novametadata_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novametadata-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novametadata + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novametadata/status + verbs: + - get diff --git a/config/rbac/novametadata_editor_role.yaml b/config/rbac/novametadata_editor_role.yaml index cf8845966..49934d1f4 100644 --- a/config/rbac/novametadata_editor_role.yaml +++ b/config/rbac/novametadata_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novametadata. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novametadata-editor-role rules: - apiGroups: diff --git a/config/rbac/novametadata_viewer_role.yaml b/config/rbac/novametadata_viewer_role.yaml index 14b8bb532..549ec42f6 100644 --- a/config/rbac/novametadata_viewer_role.yaml +++ b/config/rbac/novametadata_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novametadata. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novametadata-viewer-role rules: - apiGroups: diff --git a/config/rbac/novanovncproxy_admin_role.yaml b/config/rbac/novanovncproxy_admin_role.yaml new file mode 100644 index 000000000..c8ba584fa --- /dev/null +++ b/config/rbac/novanovncproxy_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novanovncproxy-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novanovncproxies + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novanovncproxies/status + verbs: + - get diff --git a/config/rbac/novanovncproxy_editor_role.yaml b/config/rbac/novanovncproxy_editor_role.yaml index b6685ee0b..45d62152f 100644 --- a/config/rbac/novanovncproxy_editor_role.yaml +++ b/config/rbac/novanovncproxy_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novanovncproxies. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novanovncproxy-editor-role rules: - apiGroups: diff --git a/config/rbac/novanovncproxy_viewer_role.yaml b/config/rbac/novanovncproxy_viewer_role.yaml index 98ad9f3c1..18c515f8f 100644 --- a/config/rbac/novanovncproxy_viewer_role.yaml +++ b/config/rbac/novanovncproxy_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novanovncproxies. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novanovncproxy-viewer-role rules: - apiGroups: diff --git a/config/rbac/novascheduler_admin_role.yaml b/config/rbac/novascheduler_admin_role.yaml new file mode 100644 index 000000000..fc4392f47 --- /dev/null +++ b/config/rbac/novascheduler_admin_role.yaml @@ -0,0 +1,27 @@ +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants full permissions ('*') over nova.openstack.org. +# This role is intended for users authorized to modify roles and bindings within the cluster, +# enabling them to delegate specific permissions to other users or groups as needed. + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize + name: novascheduler-admin-role +rules: +- apiGroups: + - nova.openstack.org + resources: + - novaschedulers + verbs: + - '*' +- apiGroups: + - nova.openstack.org + resources: + - novaschedulers/status + verbs: + - get diff --git a/config/rbac/novascheduler_editor_role.yaml b/config/rbac/novascheduler_editor_role.yaml index 16aec5fab..6e8bf19c3 100644 --- a/config/rbac/novascheduler_editor_role.yaml +++ b/config/rbac/novascheduler_editor_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to edit novaschedulers. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants permissions to create, update, and delete resources within the nova.openstack.org. +# This role is intended for users who need to manage these resources +# but should not control RBAC or manage permissions for others. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novascheduler-editor-role rules: - apiGroups: diff --git a/config/rbac/novascheduler_viewer_role.yaml b/config/rbac/novascheduler_viewer_role.yaml index 2f259ee92..78eb8e65e 100644 --- a/config/rbac/novascheduler_viewer_role.yaml +++ b/config/rbac/novascheduler_viewer_role.yaml @@ -1,7 +1,16 @@ -# permissions for end users to view novaschedulers. +# This rule is not used by the project nova-operator itself. +# It is provided to allow the cluster admin to help manage permissions for users. +# +# Grants read-only access to nova.openstack.org resources. +# This role is intended for users who need visibility into these resources +# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: novascheduler-viewer-role rules: - apiGroups: diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index d8702225c..dadce2740 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,6 +1,9 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io @@ -9,4 +12,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: openstack + namespace: system diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml index d67e1cf4d..11fadb81b 100644 --- a/config/rbac/service_account.yaml +++ b/config/rbac/service_account.yaml @@ -1,5 +1,8 @@ apiVersion: v1 kind: ServiceAccount metadata: + labels: + app.kubernetes.io/name: nova-operator + app.kubernetes.io/managed-by: kustomize name: controller-manager - namespace: openstack + namespace: system diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml index a9a84a85a..54e8aa507 100644 --- a/config/scorecard/kustomization.yaml +++ b/config/scorecard/kustomization.yaml @@ -1,16 +1,18 @@ resources: - bases/config.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization patches: - path: patches/basic.config.yaml target: group: scorecard.operatorframework.io - version: v1alpha3 kind: Configuration name: config + version: v1alpha3 - path: patches/olm.config.yaml target: group: scorecard.operatorframework.io - version: v1alpha3 kind: Configuration name: config -#+kubebuilder:scaffold:patches + version: v1alpha3 +# +kubebuilder:scaffold:patches diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml index 90f7ef77d..8237b70d8 100644 --- a/config/scorecard/patches/basic.config.yaml +++ b/config/scorecard/patches/basic.config.yaml @@ -4,7 +4,7 @@ entrypoint: - scorecard-test - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: basic test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml index b55840e1a..416660a77 100644 --- a/config/scorecard/patches/olm.config.yaml +++ b/config/scorecard/patches/olm.config.yaml @@ -4,7 +4,7 @@ entrypoint: - scorecard-test - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: olm test: olm-bundle-validation-test @@ -14,7 +14,7 @@ entrypoint: - scorecard-test - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: olm test: olm-crds-have-validation-test @@ -24,7 +24,7 @@ entrypoint: - scorecard-test - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: olm test: olm-crds-have-resources-test @@ -34,7 +34,7 @@ entrypoint: - scorecard-test - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: olm test: olm-spec-descriptors-test @@ -44,7 +44,7 @@ entrypoint: - scorecard-test - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.23.0 + image: quay.io/operator-framework/scorecard-test:v1.41.1 labels: suite: olm test: olm-status-descriptors-test diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml index 25e21e3c9..206316e54 100644 --- a/config/webhook/kustomizeconfig.yaml +++ b/config/webhook/kustomizeconfig.yaml @@ -1,4 +1,4 @@ -# the following config is for teaching kustomize where to look at when substituting vars. +# the following config is for teaching kustomize where to look at when substituting nameReference. # It requires kustomize v2.1.0 or newer to work properly. nameReference: - kind: Service @@ -20,6 +20,3 @@ namespace: group: admissionregistration.k8s.io path: webhooks/clientConfig/service/namespace create: true - -varReference: -- path: metadata/annotations diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index ac5f1acc1..ebdcbaaaf 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -12,7 +12,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-nova failurePolicy: Fail - name: mnova.kb.io + name: mnova-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -32,7 +32,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novaapi failurePolicy: Fail - name: mnovaapi.kb.io + name: mnovaapi-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -52,7 +52,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novacell failurePolicy: Fail - name: mnovacell.kb.io + name: mnovacell-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -72,7 +72,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novacompute failurePolicy: Fail - name: mnovacompute.kb.io + name: mnovacompute-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -92,7 +92,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novaconductor failurePolicy: Fail - name: mnovaconductor.kb.io + name: mnovaconductor-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -112,7 +112,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novametadata failurePolicy: Fail - name: mnovametadata.kb.io + name: mnovametadata-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -132,7 +132,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novanovncproxy failurePolicy: Fail - name: mnovanovncproxy.kb.io + name: mnovanovncproxy-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -152,7 +152,7 @@ webhooks: namespace: system path: /mutate-nova-openstack-org-v1beta1-novascheduler failurePolicy: Fail - name: mnovascheduler.kb.io + name: mnovascheduler-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -178,7 +178,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-nova failurePolicy: Fail - name: vnova.kb.io + name: vnova-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -198,7 +198,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novaapi failurePolicy: Fail - name: vnovaapi.kb.io + name: vnovaapi-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -218,7 +218,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novacell failurePolicy: Fail - name: vnovacell.kb.io + name: vnovacell-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -238,7 +238,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novacompute failurePolicy: Fail - name: vnovacompute.kb.io + name: vnovacompute-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -258,7 +258,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novaconductor failurePolicy: Fail - name: vnovaconductor.kb.io + name: vnovaconductor-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -278,7 +278,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novametadata failurePolicy: Fail - name: vnovametadata.kb.io + name: vnovametadata-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -298,7 +298,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novanovncproxy failurePolicy: Fail - name: vnovanovncproxy.kb.io + name: vnovanovncproxy-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org @@ -318,7 +318,7 @@ webhooks: namespace: system path: /validate-nova-openstack-org-v1beta1-novascheduler failurePolicy: Fail - name: vnovascheduler.kb.io + name: vnovascheduler-v1beta1.kb.io rules: - apiGroups: - nova.openstack.org diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml index 74ca7ae9f..fd9484b10 100644 --- a/config/webhook/service.yaml +++ b/config/webhook/service.yaml @@ -1,13 +1,8 @@ - apiVersion: v1 kind: Service metadata: labels: - app.kubernetes.io/name: service - app.kubernetes.io/instance: webhook-service - app.kubernetes.io/component: webhook - app.kubernetes.io/created-by: nova-operator - app.kubernetes.io/part-of: nova-operator + app.kubernetes.io/name: nova-operator app.kubernetes.io/managed-by: kustomize name: webhook-service namespace: system @@ -15,6 +10,7 @@ spec: ports: - port: 443 protocol: TCP - targetPort: 9444 + targetPort: 9443 selector: - openstack.org/operator-name: nova + control-plane: controller-manager + app.kubernetes.io/name: nova-operator diff --git a/go.mod b/go.mod index f6496974f..07230445e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251027074845-ed8154b20ad1 github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251027074416-ab5c045dbe00 github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251027074416-ab5c045dbe00 - github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251027074416-ab5c045dbe00 + github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20250929092825-4c2402451077 github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251015110425-ad0381ce8cd4 github.com/openstack-k8s-operators/nova-operator/api v0.0.0-20221209164002-f9e6b9363961 go.uber.org/zap v1.27.0 @@ -29,13 +29,19 @@ require ( require ( github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect @@ -44,10 +50,13 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.20.1 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.9.0 // indirect @@ -63,8 +72,19 @@ require ( github.com/prometheus/procfs v0.16.1 // indirect github.com/rabbitmq/cluster-operator/v2 v2.16.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/spf13/cobra v1.9.1 // indirect github.com/spf13/pflag v1.0.7 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect @@ -79,11 +99,18 @@ require ( golang.org/x/time v0.12.0 // indirect golang.org/x/tools v0.36.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/grpc v1.71.1 // indirect google.golang.org/protobuf v1.36.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.33.2 // indirect + k8s.io/apiserver v0.33.2 // indirect + k8s.io/component-base v0.33.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250902184714-7fc278399c7f // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect diff --git a/go.sum b/go.sum index c727cee93..d4adef9ee 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,18 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -14,6 +23,8 @@ github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= @@ -24,8 +35,11 @@ github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZ github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= @@ -44,6 +58,8 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= +github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -58,8 +74,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gophercloud/gophercloud/v2 v2.8.0 h1:of2+8tT6+FbEYHfYC8GBu8TXJNsXYSNm9KuvpX7Neqo= github.com/gophercloud/gophercloud/v2 v2.8.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= @@ -108,8 +128,8 @@ github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.2025102 github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251027074416-ab5c045dbe00/go.mod h1:yf13jWb60XV26eA7A8o86ZCXNWBLNK9dPkTSWFaTPCw= github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250929092825-4c2402451077 h1:9tpPDBV2RLXMDgt13ec8XR2OatFriItseqg+Oyvx9GA= github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20250929092825-4c2402451077/go.mod h1:JPQHkExlxeT6MU3DNJgXXJJG0NMQHlZwxxfbYRaP3eg= -github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251027074416-ab5c045dbe00 h1:2pRRZgTqfYPAUM11AqeDbxKlgIvaLCzP0OGMfW9xAiE= -github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251027074416-ab5c045dbe00/go.mod h1:BGPgBOz+Af5UqBMLeizN2OsKdXzOXQBDkilVpwi443E= +github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20250929092825-4c2402451077 h1:h11tW/Ntg9OiKCnKVAMgR+ka12597ai31OeAD1FGa4s= +github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20250929092825-4c2402451077/go.mod h1:tWZFuXyOZZI+h4uAwaBqyRcvpN7f+PGTHYRDV9VltOk= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251015110425-ad0381ce8cd4 h1:4qDSDLX7HpCIdnlUExyPc3DkyCq+73PLPb99FVj1CZk= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251015110425-ad0381ce8cd4/go.mod h1:lOZNSKG7MMkhMjL7OQXKscy+dH2mxs3HPD+oj4wVytA= github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc= @@ -133,10 +153,17 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -151,6 +178,26 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -210,6 +257,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -219,6 +272,9 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.31.13 h1:sco9Cq2pY4Ysv9qZiWzcR97MmA/35nwYQ/VCTzOcWmc= @@ -227,14 +283,20 @@ k8s.io/apiextensions-apiserver v0.31.13 h1:8xtWKVpV/YbYX0UX2k6w+cgxfxKhX0UNGuo/V k8s.io/apiextensions-apiserver v0.31.13/go.mod h1:zxpMLWXBxnJqKUIruJ+ulP+Xlfe5lPZPxq1z0cLwA2U= k8s.io/apimachinery v0.31.13 h1:rkG0EiBkBkEzURo/8dKGx/oBF202Z2LqHuSD8Cm3bG4= k8s.io/apimachinery v0.31.13/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apiserver v0.31.13 h1:Ke9/X2m3vHSgsminpAbUxULDNMbvAfjrRX73Gqx6CZc= +k8s.io/apiserver v0.31.13/go.mod h1:5nBPhL2g7am/CS+/OI5A6+olEbo0C7tQ8QNDODLd+WY= k8s.io/client-go v0.31.13 h1:Q0LG51uFbzNd9fzIj5ilA0Sm1wUholHvDaNwVKzqdCA= k8s.io/client-go v0.31.13/go.mod h1:UB4yTzQeRAv+vULOKp2jdqA5LSwV55bvc3RQ5tM48LM= +k8s.io/component-base v0.31.13 h1:/uVLq7yHk9azReqeCFAZSr/8NXydzpz7yDZ6p/yiwBQ= +k8s.io/component-base v0.31.13/go.mod h1:uMXtKNyDqeNdZYL6SRCr9wB6FutL9pOlQmkK2dRVAKQ= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e h1:UGI9rv1A2cV87NhXr4s+AUBxIuoo/SME/IyJ3b6KztE= k8s.io/kube-openapi v0.0.0-20250627150254-e9823e99808e/go.mod h1:GLOk5B+hDbRROvt0X2+hqX64v/zO3vXN7J78OUmBSKw= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.19.7 h1:DLABZfMr20A+AwCZOHhcbcu+TqBXnJZaVBri9K3EO48= sigs.k8s.io/controller-runtime v0.19.7/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= diff --git a/controllers/common.go b/internal/controller/common.go similarity index 99% rename from controllers/common.go rename to internal/controller/common.go index 50d2993c3..ec23010aa 100644 --- a/controllers/common.go +++ b/internal/controller/common.go @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package controllers contains the Nova operator controllers for managing OpenStack Nova services. -package controllers +// Package controller contains the Nova operator controllers for managing OpenStack Nova services. +package controller import ( "context" @@ -40,7 +40,7 @@ import ( memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" gophercloud "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/services" diff --git a/controllers/nova_controller.go b/internal/controller/nova_controller.go similarity index 99% rename from controllers/nova_controller.go rename to internal/controller/nova_controller.go index 73c6f436f..f59d01c6e 100644 --- a/controllers/nova_controller.go +++ b/internal/controller/nova_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -54,8 +54,8 @@ import ( util "github.com/openstack-k8s-operators/lib-common/modules/common/util" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novaapi" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novaapi" memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" diff --git a/controllers/novaapi_controller.go b/internal/controller/novaapi_controller.go similarity index 99% rename from controllers/novaapi_controller.go rename to internal/controller/novaapi_controller.go index ba9d6e46c..f49dea5f5 100644 --- a/controllers/novaapi_controller.go +++ b/internal/controller/novaapi_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -54,8 +54,8 @@ import ( topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novaapi" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novaapi" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ) diff --git a/controllers/novacell_controller.go b/internal/controller/novacell_controller.go similarity index 99% rename from controllers/novacell_controller.go rename to internal/controller/novacell_controller.go index bb60d1424..1a2465fb2 100644 --- a/controllers/novacell_controller.go +++ b/internal/controller/novacell_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" diff --git a/controllers/novacompute_controller.go b/internal/controller/novacompute_controller.go similarity index 99% rename from controllers/novacompute_controller.go rename to internal/controller/novacompute_controller.go index d317250db..b25dde963 100644 --- a/controllers/novacompute_controller.go +++ b/internal/controller/novacompute_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -48,8 +48,8 @@ import ( util "github.com/openstack-k8s-operators/lib-common/modules/common/util" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novacompute" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novacompute" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" k8s_errors "k8s.io/apimachinery/pkg/api/errors" diff --git a/controllers/novaconductor_controller.go b/internal/controller/novaconductor_controller.go similarity index 99% rename from controllers/novaconductor_controller.go rename to internal/controller/novaconductor_controller.go index 61f3a3292..bf48fab2a 100644 --- a/controllers/novaconductor_controller.go +++ b/internal/controller/novaconductor_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -54,7 +54,7 @@ import ( util "github.com/openstack-k8s-operators/lib-common/modules/common/util" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/novaconductor" + "github.com/openstack-k8s-operators/nova-operator/internal/novaconductor" ) // NovaConductorReconciler reconciles a NovaConductor object diff --git a/controllers/novametadata_controller.go b/internal/controller/novametadata_controller.go similarity index 99% rename from controllers/novametadata_controller.go rename to internal/controller/novametadata_controller.go index 829c0f782..4aa1d4da5 100644 --- a/controllers/novametadata_controller.go +++ b/internal/controller/novametadata_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -54,8 +54,8 @@ import ( util "github.com/openstack-k8s-operators/lib-common/modules/common/util" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novametadata" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novametadata" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ) diff --git a/controllers/novanovncproxy_controller.go b/internal/controller/novanovncproxy_controller.go similarity index 99% rename from controllers/novanovncproxy_controller.go rename to internal/controller/novanovncproxy_controller.go index 2199f04eb..15ad06d44 100644 --- a/controllers/novanovncproxy_controller.go +++ b/internal/controller/novanovncproxy_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -51,8 +51,8 @@ import ( util "github.com/openstack-k8s-operators/lib-common/modules/common/util" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novncproxy" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novncproxy" k8s_errors "k8s.io/apimachinery/pkg/api/errors" ) diff --git a/controllers/novascheduler_controller.go b/internal/controller/novascheduler_controller.go similarity index 99% rename from controllers/novascheduler_controller.go rename to internal/controller/novascheduler_controller.go index e9a07a9b9..3b8c7f5ba 100644 --- a/controllers/novascheduler_controller.go +++ b/internal/controller/novascheduler_controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controllers +package controller import ( "context" @@ -52,8 +52,8 @@ import ( topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" - "github.com/openstack-k8s-operators/nova-operator/pkg/novascheduler" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/novascheduler" ) // NovaSchedulerReconciler reconciles a NovaScheduler object diff --git a/pkg/nova/celldelete.go b/internal/nova/celldelete.go similarity index 100% rename from pkg/nova/celldelete.go rename to internal/nova/celldelete.go diff --git a/pkg/nova/cellmapping.go b/internal/nova/cellmapping.go similarity index 100% rename from pkg/nova/cellmapping.go rename to internal/nova/cellmapping.go diff --git a/pkg/nova/common.go b/internal/nova/common.go similarity index 100% rename from pkg/nova/common.go rename to internal/nova/common.go diff --git a/pkg/nova/host_discover.go b/internal/nova/host_discover.go similarity index 100% rename from pkg/nova/host_discover.go rename to internal/nova/host_discover.go diff --git a/pkg/nova/volumes.go b/internal/nova/volumes.go similarity index 100% rename from pkg/nova/volumes.go rename to internal/nova/volumes.go diff --git a/pkg/novaapi/const.go b/internal/novaapi/const.go similarity index 100% rename from pkg/novaapi/const.go rename to internal/novaapi/const.go diff --git a/pkg/novaapi/deployment.go b/internal/novaapi/deployment.go similarity index 99% rename from pkg/novaapi/deployment.go rename to internal/novaapi/deployment.go index 839afff25..2f32b6639 100644 --- a/pkg/novaapi/deployment.go +++ b/internal/novaapi/deployment.go @@ -25,7 +25,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/tls" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/pkg/novacompute/deployment.go b/internal/novacompute/deployment.go similarity index 98% rename from pkg/novacompute/deployment.go rename to internal/novacompute/deployment.go index 54d41d44e..4e058fa39 100644 --- a/pkg/novacompute/deployment.go +++ b/internal/novacompute/deployment.go @@ -22,7 +22,7 @@ import ( affinity "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" appsv1 "k8s.io/api/apps/v1" diff --git a/pkg/novaconductor/dbpurge.go b/internal/novaconductor/dbpurge.go similarity index 98% rename from pkg/novaconductor/dbpurge.go rename to internal/novaconductor/dbpurge.go index beabb5460..18ecf83cc 100644 --- a/pkg/novaconductor/dbpurge.go +++ b/internal/novaconductor/dbpurge.go @@ -13,7 +13,7 @@ import ( memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" ) // DBPurgeCronJob creates a Kubernetes CronJob for purging old Nova database records diff --git a/pkg/novaconductor/dbsync.go b/internal/novaconductor/dbsync.go similarity index 98% rename from pkg/novaconductor/dbsync.go rename to internal/novaconductor/dbsync.go index ce8b31939..a9e1f2d78 100644 --- a/pkg/novaconductor/dbsync.go +++ b/internal/novaconductor/dbsync.go @@ -18,7 +18,7 @@ package novaconductor import ( novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" diff --git a/pkg/novaconductor/deployment.go b/internal/novaconductor/deployment.go similarity index 98% rename from pkg/novaconductor/deployment.go rename to internal/novaconductor/deployment.go index 4cc73351b..31bf7af99 100644 --- a/pkg/novaconductor/deployment.go +++ b/internal/novaconductor/deployment.go @@ -23,7 +23,7 @@ import ( affinity "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/pkg/novametadata/const.go b/internal/novametadata/const.go similarity index 100% rename from pkg/novametadata/const.go rename to internal/novametadata/const.go diff --git a/pkg/novametadata/deployment.go b/internal/novametadata/deployment.go similarity index 99% rename from pkg/novametadata/deployment.go rename to internal/novametadata/deployment.go index 6e74329e3..6eccf3b95 100644 --- a/pkg/novametadata/deployment.go +++ b/internal/novametadata/deployment.go @@ -23,7 +23,7 @@ import ( affinity "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/pkg/novascheduler/deployment.go b/internal/novascheduler/deployment.go similarity index 98% rename from pkg/novascheduler/deployment.go rename to internal/novascheduler/deployment.go index fef5e125e..e3fad7f92 100644 --- a/pkg/novascheduler/deployment.go +++ b/internal/novascheduler/deployment.go @@ -22,7 +22,7 @@ import ( affinity "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" diff --git a/pkg/novncproxy/const.go b/internal/novncproxy/const.go similarity index 100% rename from pkg/novncproxy/const.go rename to internal/novncproxy/const.go diff --git a/pkg/novncproxy/deployment.go b/internal/novncproxy/deployment.go similarity index 98% rename from pkg/novncproxy/deployment.go rename to internal/novncproxy/deployment.go index c7c9b7613..325dfe244 100644 --- a/pkg/novncproxy/deployment.go +++ b/internal/novncproxy/deployment.go @@ -23,7 +23,7 @@ import ( affinity "github.com/openstack-k8s-operators/lib-common/modules/common/affinity" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/pkg/nova" + "github.com/openstack-k8s-operators/nova-operator/internal/nova" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/internal/webhook/v1beta1/nova_webhook.go b/internal/webhook/v1beta1/nova_webhook.go new file mode 100644 index 000000000..8e42f9c05 --- /dev/null +++ b/internal/webhook/v1beta1/nova_webhook.go @@ -0,0 +1,126 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 implements webhooks for Nova v1beta1 API +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novalog = logf.Log.WithName("nova-resource") + +var ( + errUnexpectedObjectType = errors.New("unexpected object type") +) + +// SetupNovaWebhookWithManager registers the webhook for Nova in the manager. +func SetupNovaWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.Nova{}). + WithValidator(&NovaCustomValidator{}). + WithDefaulter(&NovaCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-nova,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=nova,verbs=create;update,versions=v1beta1,name=mnova-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind Nova when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Nova. +func (d *NovaCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + nova, ok := obj.(*novav1beta1.Nova) + + if !ok { + return fmt.Errorf("%w: expected an Nova object but got %T", errUnexpectedObjectType, obj) + } + novalog.Info("Defaulting for Nova", "name", nova.GetName()) + + nova.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-nova,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=nova,verbs=create;update,versions=v1beta1,name=vnova-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaCustomValidator struct is responsible for validating the Nova resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type Nova. +func (v *NovaCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + nova, ok := obj.(*novav1beta1.Nova) + if !ok { + return nil, fmt.Errorf("%w: expected a Nova object but got %T", errUnexpectedObjectType, obj) + } + novalog.Info("Validation for Nova upon creation", "name", nova.GetName()) + + return nova.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type Nova. +func (v *NovaCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + nova, ok := newObj.(*novav1beta1.Nova) + if !ok { + return nil, fmt.Errorf("%w: expected a Nova object for the newObj but got %T", errUnexpectedObjectType, newObj) + } + novalog.Info("Validation for Nova upon update", "name", nova.GetName()) + + return nova.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type Nova. +func (v *NovaCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + nova, ok := obj.(*novav1beta1.Nova) + if !ok { + return nil, fmt.Errorf("%w: expected a Nova object but got %T", errUnexpectedObjectType, obj) + } + novalog.Info("Validation for Nova upon deletion", "name", nova.GetName()) + + return nova.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novaapi_webhook.go b/internal/webhook/v1beta1/novaapi_webhook.go new file mode 100644 index 000000000..0d43f734f --- /dev/null +++ b/internal/webhook/v1beta1/novaapi_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novaapilog = logf.Log.WithName("novaapi-resource") + +var errExpectedNovaAPIObject = errors.New("expected a NovaAPI object") + +// SetupNovaAPIWebhookWithManager registers the webhook for NovaAPI in the manager. +func SetupNovaAPIWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaAPI{}). + WithValidator(&NovaAPICustomValidator{}). + WithDefaulter(&NovaAPICustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novaapi,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaapis,verbs=create;update,versions=v1beta1,name=mnovaapi-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaAPICustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaAPI when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaAPICustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaAPICustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaAPI. +func (d *NovaAPICustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novaapi, ok := obj.(*novav1beta1.NovaAPI) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaAPIObject, obj) + } + novaapilog.Info("Defaulting for NovaAPI", "name", novaapi.GetName()) + + novaapi.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novaapi,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaapis,verbs=create;update,versions=v1beta1,name=vnovaapi-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaAPICustomValidator struct is responsible for validating the NovaAPI resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaAPICustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaAPICustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaAPI. +func (v *NovaAPICustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novaapi, ok := obj.(*novav1beta1.NovaAPI) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaAPIObject, obj) + } + novaapilog.Info("Validation for NovaAPI upon creation", "name", novaapi.GetName()) + + return novaapi.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaAPI. +func (v *NovaAPICustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novaapi, ok := newObj.(*novav1beta1.NovaAPI) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaAPIObject, newObj) + } + novaapilog.Info("Validation for NovaAPI upon update", "name", novaapi.GetName()) + + return novaapi.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaAPI. +func (v *NovaAPICustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novaapi, ok := obj.(*novav1beta1.NovaAPI) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaAPIObject, obj) + } + novaapilog.Info("Validation for NovaAPI upon deletion", "name", novaapi.GetName()) + + return novaapi.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novacell_webhook.go b/internal/webhook/v1beta1/novacell_webhook.go new file mode 100644 index 000000000..ffbb8ab2e --- /dev/null +++ b/internal/webhook/v1beta1/novacell_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novacelllog = logf.Log.WithName("novacell-resource") + +var errExpectedNovaCellObject = errors.New("expected a NovaCell object") + +// SetupNovaCellWebhookWithManager registers the webhook for NovaCell in the manager. +func SetupNovaCellWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaCell{}). + WithValidator(&NovaCellCustomValidator{}). + WithDefaulter(&NovaCellCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novacell,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacells,verbs=create;update,versions=v1beta1,name=mnovacell-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaCellCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaCell when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaCellCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaCellCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaCell. +func (d *NovaCellCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novacell, ok := obj.(*novav1beta1.NovaCell) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaCellObject, obj) + } + novacelllog.Info("Defaulting for NovaCell", "name", novacell.GetName()) + + novacell.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novacell,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacells,verbs=create;update,versions=v1beta1,name=vnovacell-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaCellCustomValidator struct is responsible for validating the NovaCell resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaCellCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaCellCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaCell. +func (v *NovaCellCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novacell, ok := obj.(*novav1beta1.NovaCell) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaCellObject, obj) + } + novacelllog.Info("Validation for NovaCell upon creation", "name", novacell.GetName()) + + return novacell.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaCell. +func (v *NovaCellCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novacell, ok := newObj.(*novav1beta1.NovaCell) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaCellObject, newObj) + } + novacelllog.Info("Validation for NovaCell upon update", "name", novacell.GetName()) + + return novacell.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaCell. +func (v *NovaCellCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novacell, ok := obj.(*novav1beta1.NovaCell) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaCellObject, obj) + } + novacelllog.Info("Validation for NovaCell upon deletion", "name", novacell.GetName()) + + return novacell.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novacompute_webhook.go b/internal/webhook/v1beta1/novacompute_webhook.go new file mode 100644 index 000000000..832e6a416 --- /dev/null +++ b/internal/webhook/v1beta1/novacompute_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novacomputelog = logf.Log.WithName("novacompute-resource") + +var errExpectedNovaComputeObject = errors.New("expected a NovaCompute object") + +// SetupNovaComputeWebhookWithManager registers the webhook for NovaCompute in the manager. +func SetupNovaComputeWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaCompute{}). + WithValidator(&NovaComputeCustomValidator{}). + WithDefaulter(&NovaComputeCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novacompute,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacomputes,verbs=create;update,versions=v1beta1,name=mnovacompute-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaComputeCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaCompute when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaComputeCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaComputeCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaCompute. +func (d *NovaComputeCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novacompute, ok := obj.(*novav1beta1.NovaCompute) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaComputeObject, obj) + } + novacomputelog.Info("Defaulting for NovaCompute", "name", novacompute.GetName()) + + novacompute.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novacompute,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novacomputes,verbs=create;update,versions=v1beta1,name=vnovacompute-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaComputeCustomValidator struct is responsible for validating the NovaCompute resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaComputeCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaComputeCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaCompute. +func (v *NovaComputeCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novacompute, ok := obj.(*novav1beta1.NovaCompute) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaComputeObject, obj) + } + novacomputelog.Info("Validation for NovaCompute upon creation", "name", novacompute.GetName()) + + return novacompute.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaCompute. +func (v *NovaComputeCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novacompute, ok := newObj.(*novav1beta1.NovaCompute) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaComputeObject, newObj) + } + novacomputelog.Info("Validation for NovaCompute upon update", "name", novacompute.GetName()) + + return novacompute.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaCompute. +func (v *NovaComputeCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novacompute, ok := obj.(*novav1beta1.NovaCompute) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaComputeObject, obj) + } + novacomputelog.Info("Validation for NovaCompute upon deletion", "name", novacompute.GetName()) + + return novacompute.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novaconductor_webhook.go b/internal/webhook/v1beta1/novaconductor_webhook.go new file mode 100644 index 000000000..dfbc559bc --- /dev/null +++ b/internal/webhook/v1beta1/novaconductor_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novaconductorlog = logf.Log.WithName("novaconductor-resource") + +var errExpectedNovaConductorObject = errors.New("expected a NovaConductor object") + +// SetupNovaConductorWebhookWithManager registers the webhook for NovaConductor in the manager. +func SetupNovaConductorWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaConductor{}). + WithValidator(&NovaConductorCustomValidator{}). + WithDefaulter(&NovaConductorCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novaconductor,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaconductors,verbs=create;update,versions=v1beta1,name=mnovaconductor-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaConductorCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaConductor when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaConductorCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaConductorCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaConductor. +func (d *NovaConductorCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novaconductor, ok := obj.(*novav1beta1.NovaConductor) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaConductorObject, obj) + } + novaconductorlog.Info("Defaulting for NovaConductor", "name", novaconductor.GetName()) + + novaconductor.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novaconductor,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaconductors,verbs=create;update,versions=v1beta1,name=vnovaconductor-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaConductorCustomValidator struct is responsible for validating the NovaConductor resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaConductorCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaConductorCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaConductor. +func (v *NovaConductorCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novaconductor, ok := obj.(*novav1beta1.NovaConductor) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaConductorObject, obj) + } + novaconductorlog.Info("Validation for NovaConductor upon creation", "name", novaconductor.GetName()) + + return novaconductor.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaConductor. +func (v *NovaConductorCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novaconductor, ok := newObj.(*novav1beta1.NovaConductor) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaConductorObject, newObj) + } + novaconductorlog.Info("Validation for NovaConductor upon update", "name", novaconductor.GetName()) + + return novaconductor.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaConductor. +func (v *NovaConductorCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novaconductor, ok := obj.(*novav1beta1.NovaConductor) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaConductorObject, obj) + } + novaconductorlog.Info("Validation for NovaConductor upon deletion", "name", novaconductor.GetName()) + + return novaconductor.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novametadata_webhook.go b/internal/webhook/v1beta1/novametadata_webhook.go new file mode 100644 index 000000000..5dd2e8207 --- /dev/null +++ b/internal/webhook/v1beta1/novametadata_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novametadatalog = logf.Log.WithName("novametadata-resource") + +var errExpectedNovaMetadataObject = errors.New("expected a NovaMetadata object") + +// SetupNovaMetadataWebhookWithManager registers the webhook for NovaMetadata in the manager. +func SetupNovaMetadataWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaMetadata{}). + WithValidator(&NovaMetadataCustomValidator{}). + WithDefaulter(&NovaMetadataCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novametadata,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novametadata,verbs=create;update,versions=v1beta1,name=mnovametadata-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaMetadataCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaMetadata when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaMetadataCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaMetadataCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaMetadata. +func (d *NovaMetadataCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novametadata, ok := obj.(*novav1beta1.NovaMetadata) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaMetadataObject, obj) + } + novametadatalog.Info("Defaulting for NovaMetadata", "name", novametadata.GetName()) + + novametadata.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novametadata,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novametadata,verbs=create;update,versions=v1beta1,name=vnovametadata-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaMetadataCustomValidator struct is responsible for validating the NovaMetadata resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaMetadataCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaMetadataCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaMetadata. +func (v *NovaMetadataCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novametadata, ok := obj.(*novav1beta1.NovaMetadata) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaMetadataObject, obj) + } + novametadatalog.Info("Validation for NovaMetadata upon creation", "name", novametadata.GetName()) + + return novametadata.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaMetadata. +func (v *NovaMetadataCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novametadata, ok := newObj.(*novav1beta1.NovaMetadata) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaMetadataObject, newObj) + } + novametadatalog.Info("Validation for NovaMetadata upon update", "name", novametadata.GetName()) + + return novametadata.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaMetadata. +func (v *NovaMetadataCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novametadata, ok := obj.(*novav1beta1.NovaMetadata) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaMetadataObject, obj) + } + novametadatalog.Info("Validation for NovaMetadata upon deletion", "name", novametadata.GetName()) + + return novametadata.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novanovncproxy_webhook.go b/internal/webhook/v1beta1/novanovncproxy_webhook.go new file mode 100644 index 000000000..ab6ef86d1 --- /dev/null +++ b/internal/webhook/v1beta1/novanovncproxy_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novanovncproxylog = logf.Log.WithName("novanovncproxy-resource") + +var errExpectedNovaNoVNCProxyObject = errors.New("expected a NovaNoVNCProxy object") + +// SetupNovaNoVNCProxyWebhookWithManager registers the webhook for NovaNoVNCProxy in the manager. +func SetupNovaNoVNCProxyWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaNoVNCProxy{}). + WithValidator(&NovaNoVNCProxyCustomValidator{}). + WithDefaulter(&NovaNoVNCProxyCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novanovncproxy,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novanovncproxies,verbs=create;update,versions=v1beta1,name=mnovanovncproxy-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaNoVNCProxyCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaNoVNCProxy when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaNoVNCProxyCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaNoVNCProxyCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaNoVNCProxy. +func (d *NovaNoVNCProxyCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novanovncproxy, ok := obj.(*novav1beta1.NovaNoVNCProxy) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaNoVNCProxyObject, obj) + } + novanovncproxylog.Info("Defaulting for NovaNoVNCProxy", "name", novanovncproxy.GetName()) + + novanovncproxy.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novanovncproxy,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novanovncproxies,verbs=create;update,versions=v1beta1,name=vnovanovncproxy-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaNoVNCProxyCustomValidator struct is responsible for validating the NovaNoVNCProxy resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaNoVNCProxyCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaNoVNCProxyCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaNoVNCProxy. +func (v *NovaNoVNCProxyCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novanovncproxy, ok := obj.(*novav1beta1.NovaNoVNCProxy) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaNoVNCProxyObject, obj) + } + novanovncproxylog.Info("Validation for NovaNoVNCProxy upon creation", "name", novanovncproxy.GetName()) + + return novanovncproxy.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaNoVNCProxy. +func (v *NovaNoVNCProxyCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novanovncproxy, ok := newObj.(*novav1beta1.NovaNoVNCProxy) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaNoVNCProxyObject, newObj) + } + novanovncproxylog.Info("Validation for NovaNoVNCProxy upon update", "name", novanovncproxy.GetName()) + + return novanovncproxy.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaNoVNCProxy. +func (v *NovaNoVNCProxyCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novanovncproxy, ok := obj.(*novav1beta1.NovaNoVNCProxy) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaNoVNCProxyObject, obj) + } + novanovncproxylog.Info("Validation for NovaNoVNCProxy upon deletion", "name", novanovncproxy.GetName()) + + return novanovncproxy.ValidateDelete() +} diff --git a/internal/webhook/v1beta1/novascheduler_webhook.go b/internal/webhook/v1beta1/novascheduler_webhook.go new file mode 100644 index 000000000..25475e18e --- /dev/null +++ b/internal/webhook/v1beta1/novascheduler_webhook.go @@ -0,0 +1,123 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + novav1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" +) + +// nolint:unused +// log is for logging in this package. +var novaschedulerlog = logf.Log.WithName("novascheduler-resource") + +var errExpectedNovaSchedulerObject = errors.New("expected a NovaScheduler object") + +// SetupNovaSchedulerWebhookWithManager registers the webhook for NovaScheduler in the manager. +func SetupNovaSchedulerWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr).For(&novav1beta1.NovaScheduler{}). + WithValidator(&NovaSchedulerCustomValidator{}). + WithDefaulter(&NovaSchedulerCustomDefaulter{}). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +// +kubebuilder:webhook:path=/mutate-nova-openstack-org-v1beta1-novascheduler,mutating=true,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaschedulers,verbs=create;update,versions=v1beta1,name=mnovascheduler-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaSchedulerCustomDefaulter struct is responsible for setting default values on the custom resource of the +// Kind NovaScheduler when those are created or updated. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as it is used only for temporary operations and does not need to be deeply copied. +type NovaSchedulerCustomDefaulter struct { + // TODO(user): Add more fields as needed for defaulting +} + +var _ webhook.CustomDefaulter = &NovaSchedulerCustomDefaulter{} + +// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind NovaScheduler. +func (d *NovaSchedulerCustomDefaulter) Default(_ context.Context, obj runtime.Object) error { + novascheduler, ok := obj.(*novav1beta1.NovaScheduler) + + if !ok { + return fmt.Errorf("%w but got %T", errExpectedNovaSchedulerObject, obj) + } + novaschedulerlog.Info("Defaulting for NovaScheduler", "name", novascheduler.GetName()) + + novascheduler.Default() + + return nil +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +// NOTE: The 'path' attribute must follow a specific pattern and should not be modified directly here. +// Modifying the path for an invalid path can cause API server errors; failing to locate the webhook. +// +kubebuilder:webhook:path=/validate-nova-openstack-org-v1beta1-novascheduler,mutating=false,failurePolicy=fail,sideEffects=None,groups=nova.openstack.org,resources=novaschedulers,verbs=create;update,versions=v1beta1,name=vnovascheduler-v1beta1.kb.io,admissionReviewVersions=v1 + +// NovaSchedulerCustomValidator struct is responsible for validating the NovaScheduler resource +// when it is created, updated, or deleted. +// +// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen from generating DeepCopy methods, +// as this struct is used only for temporary operations and does not need to be deeply copied. +type NovaSchedulerCustomValidator struct { + // TODO(user): Add more fields as needed for validation +} + +var _ webhook.CustomValidator = &NovaSchedulerCustomValidator{} + +// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type NovaScheduler. +func (v *NovaSchedulerCustomValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novascheduler, ok := obj.(*novav1beta1.NovaScheduler) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaSchedulerObject, obj) + } + novaschedulerlog.Info("Validation for NovaScheduler upon creation", "name", novascheduler.GetName()) + + return novascheduler.ValidateCreate() +} + +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type NovaScheduler. +func (v *NovaSchedulerCustomValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + novascheduler, ok := newObj.(*novav1beta1.NovaScheduler) + if !ok { + return nil, fmt.Errorf("%w for the newObj but got %T", errExpectedNovaSchedulerObject, newObj) + } + novaschedulerlog.Info("Validation for NovaScheduler upon update", "name", novascheduler.GetName()) + + return novascheduler.ValidateUpdate(oldObj) +} + +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type NovaScheduler. +func (v *NovaSchedulerCustomValidator) ValidateDelete(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + novascheduler, ok := obj.(*novav1beta1.NovaScheduler) + if !ok { + return nil, fmt.Errorf("%w but got %T", errExpectedNovaSchedulerObject, obj) + } + novaschedulerlog.Info("Validation for NovaScheduler upon deletion", "name", novascheduler.GetName()) + + return novascheduler.ValidateDelete() +} diff --git a/main.go b/main.go deleted file mode 100644 index 5c7a63fdd..000000000 --- a/main.go +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package main implements the nova-operator controller manager. -package main - -import ( - "crypto/tls" - "flag" - "os" - "strings" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - - "go.uber.org/zap/zapcore" - "k8s.io/client-go/kubernetes" - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client/config" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" - "github.com/openstack-k8s-operators/lib-common/modules/common/operator" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - - rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" - keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" - mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" - - topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" - novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - - "github.com/openstack-k8s-operators/nova-operator/controllers" - //+kubebuilder:scaffold:imports -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(novav1.AddToScheme(scheme)) - utilruntime.Must(mariadbv1.AddToScheme(scheme)) - utilruntime.Must(keystonev1.AddToScheme(scheme)) - utilruntime.Must(corev1.AddToScheme(scheme)) - utilruntime.Must(appsv1.AddToScheme(scheme)) - utilruntime.Must(rabbitmqv1.AddToScheme(scheme)) - utilruntime.Must(networkv1.AddToScheme(scheme)) - utilruntime.Must(memcachedv1.AddToScheme(scheme)) - utilruntime.Must(topologyv1.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme -} - -func main() { - var metricsAddr string - var enableLeaderElection bool - var probeAddr string - var pprofBindAddress string - var webhookPort int - var enableHTTP2 bool - flag.BoolVar(&enableHTTP2, "enable-http2", enableHTTP2, "If HTTP/2 should be enabled for the metrics and webhook servers.") - flag.StringVar(&metricsAddr, "metrics-bind-address", ":24600", "The address the metric endpoint binds to.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":24601", "The address the probe endpoint binds to.") - flag.StringVar(&pprofBindAddress, "pprof-bind-address", "", "The address the pprof endpoint binds to. Set to empty to disable pprof.") - flag.IntVar(&webhookPort, "webhook-bind-address", 9444, "The port the webhook server binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - opts := zap.Options{ - Development: true, - TimeEncoder: zapcore.ISO8601TimeEncoder, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - disableHTTP2 := func(c *tls.Config) { - if enableHTTP2 { - return - } - c.NextProtos = []string{"http/1.1"} - } - - options := ctrl.Options{ - Scheme: scheme, - Metrics: metricsserver.Options{ - BindAddress: metricsAddr, - }, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "f33036c1.openstack.org", - PprofBindAddress: pprofBindAddress, - WebhookServer: webhook.NewServer( - webhook.Options{ - Port: webhookPort, - TLSOpts: []func(config *tls.Config){disableHTTP2}, - }), - } - - err := operator.SetManagerOptions(&options, setupLog) - if err != nil { - setupLog.Error(err, "unable to set manager options") - os.Exit(1) - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - cfg, err := config.GetConfig() - if err != nil { - setupLog.Error(err, "unable to get config") - os.Exit(1) - } - - kclient, err := kubernetes.NewForConfig(cfg) - if err != nil { - setupLog.Error(err, "unable to create k8s client") - os.Exit(1) - } - - reconcilers := controllers.NewReconcilers(mgr, kclient) - err = reconcilers.Setup(mgr, setupLog) - if err != nil { - os.Exit(1) - } - - // Acquire environmental defaults and initialize operator defaults with them - novav1.SetupDefaults() - - checker := healthz.Ping - // Setup webhooks if requested - if strings.ToLower(os.Getenv("ENABLE_WEBHOOKS")) != "false" { - - if err = (&novav1.Nova{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Nova") - os.Exit(1) - } - if err = (&novav1.NovaAPI{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaAPI") - os.Exit(1) - } - if err = (&novav1.NovaCell{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaCell") - os.Exit(1) - } - if err = (&novav1.NovaConductor{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaConductor") - os.Exit(1) - } - if err = (&novav1.NovaMetadata{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaMetadata") - os.Exit(1) - } - if err = (&novav1.NovaNoVNCProxy{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaNoVNCProxy") - os.Exit(1) - } - if err = (&novav1.NovaScheduler{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaScheduler") - os.Exit(1) - } - - checker = mgr.GetWebhookServer().StartedChecker() - - if err = (&novav1.NovaCompute{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "NovaCompute") - os.Exit(1) - } - } - - //+kubebuilder:scaffold:builder - - if err := mgr.AddHealthzCheck("healthz", checker); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", checker); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} diff --git a/test/functional/nova_controller_test.go b/test/functional/nova_controller_test.go index 2b91fe78b..59bd0a67f 100644 --- a/test/functional/nova_controller_test.go +++ b/test/functional/nova_controller_test.go @@ -35,7 +35,7 @@ import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/util" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/controllers" + controllers "github.com/openstack-k8s-operators/nova-operator/internal/controller" ) var _ = Describe("Nova controller - notifications", func() { diff --git a/test/functional/nova_multicell_test.go b/test/functional/nova_multicell_test.go index d8cc1d004..7b46d59ea 100644 --- a/test/functional/nova_multicell_test.go +++ b/test/functional/nova_multicell_test.go @@ -27,7 +27,7 @@ import ( condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/controllers" + controllers "github.com/openstack-k8s-operators/nova-operator/internal/controller" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/test/functional/novacell_controller_test.go b/test/functional/novacell_controller_test.go index 8e923e0bb..a5c3cc3dd 100644 --- a/test/functional/novacell_controller_test.go +++ b/test/functional/novacell_controller_test.go @@ -29,7 +29,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/service" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/controllers" + controllers "github.com/openstack-k8s-operators/nova-operator/internal/controller" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/utils/ptr" diff --git a/test/functional/suite_test.go b/test/functional/suite_test.go index b28eff989..9c69b2765 100644 --- a/test/functional/suite_test.go +++ b/test/functional/suite_test.go @@ -56,7 +56,8 @@ import ( test "github.com/openstack-k8s-operators/lib-common/modules/test" mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" - "github.com/openstack-k8s-operators/nova-operator/controllers" + controllers "github.com/openstack-k8s-operators/nova-operator/internal/controller" + webhookv1beta1 "github.com/openstack-k8s-operators/nova-operator/internal/webhook/v1beta1" infra_test "github.com/openstack-k8s-operators/infra-operator/apis/test/helpers" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" @@ -221,21 +222,21 @@ var _ = BeforeSuite(func() { // Acquire environmental defaults and initialize operator defaults with them novav1.SetupDefaults() - err = (&novav1.Nova{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaAPI{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaAPIWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaCell{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaCellWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaConductor{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaConductorWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaMetadata{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaMetadataWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaNoVNCProxy{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaNoVNCProxyWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaScheduler{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaSchedulerWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - err = (&novav1.NovaCompute{}).SetupWebhookWithManager(k8sManager) + err = webhookv1beta1.SetupNovaComputeWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) go func() {