diff --git a/api/v1beta1/common.go b/api/v1beta1/common.go index cd63e0f9..86d1939e 100644 --- a/api/v1beta1/common.go +++ b/api/v1beta1/common.go @@ -120,6 +120,16 @@ func SetupDefaults() { SetupGlanceDefaults(glanceDefaults) } +// SetupAPIDefaults - initializes any CRD field defaults based on environment variables (the defaulting mechanism itself is implemented via webhooks) +func SetupAPIDefaults() { + // Acquire environmental defaults and initialize GlanceAPI defaults with them + glanceAPIDefaults := GlanceAPIDefaults{ + ContainerImageURL: util.GetEnvVar("RELATED_IMAGE_GLANCE_API_IMAGE_URL_DEFAULT", GlanceAPIContainerImage), + } + + SetupGlanceAPIDefaults(glanceAPIDefaults) +} + // GetAdminServiceClient - get an admin serviceClient for the Glance instance func GetAdminServiceClient( ctx context.Context, diff --git a/api/v1beta1/glanceapi_webhook.go b/api/v1beta1/glanceapi_webhook.go new file mode 100644 index 00000000..dab0b6d0 --- /dev/null +++ b/api/v1beta1/glanceapi_webhook.go @@ -0,0 +1,93 @@ +/* +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 v1beta1 + +import ( + "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" +) + +// GlanceAPIDefaults - +type GlanceAPIDefaults struct { + ContainerImageURL string +} + +var glanceAPIDefaults GlanceAPIDefaults + +// log is for logging in this package. +var glanceapilog = logf.Log.WithName("glanceapi-resource") + +// SetupGlanceAPIDefaults - initialize GlanceAPI spec defaults for use with either internal or external webhooks +func SetupGlanceAPIDefaults(defaults GlanceAPIDefaults) { + glanceAPIDefaults = defaults + glancelog.Info("Glance defaults initialized", "defaults", defaults) +} + +// SetupWebhookWithManager sets up the webhook with the Manager +func (r *GlanceAPI) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +//+kubebuilder:webhook:path=/mutate-glance-openstack-org-v1beta1-glanceapi,mutating=true,failurePolicy=fail,sideEffects=None,groups=glance.openstack.org,resources=glanceapis,verbs=create;update,versions=v1beta1,name=mglanceapi.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &GlanceAPI{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *GlanceAPI) Default() { + glancelog.Info("default", "name", r.Name) + + r.Spec.Default() +} + +// Default - set defaults for this Glance spec +func (spec *GlanceAPISpec) Default() { + if spec.GlanceAPITemplate.ContainerImage == "" { + spec.GlanceAPITemplate.ContainerImage = glanceAPIDefaults.ContainerImageURL + } +} + +//+kubebuilder:webhook:path=/validate-glance-openstack-org-v1beta1-glanceapi,mutating=false,failurePolicy=fail,sideEffects=None,groups=glance.openstack.org,resources=glanceapis,verbs=create;update,versions=v1beta1,name=vglanceapi.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &GlanceAPI{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *GlanceAPI) ValidateCreate() error { + glancelog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *GlanceAPI) ValidateUpdate(old runtime.Object) error { + glancelog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *GlanceAPI) ValidateDelete() error { + glancelog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 29c46b42..67dae803 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -117,6 +117,21 @@ func (in *GlanceAPIDebug) DeepCopy() *GlanceAPIDebug { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlanceAPIDefaults) DeepCopyInto(out *GlanceAPIDefaults) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlanceAPIDefaults. +func (in *GlanceAPIDefaults) DeepCopy() *GlanceAPIDefaults { + if in == nil { + return nil + } + out := new(GlanceAPIDefaults) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GlanceAPIList) DeepCopyInto(out *GlanceAPIList) { *out = *in diff --git a/config/samples/glance_v1beta1_glanceapi.yaml b/config/samples/glance_v1beta1_glanceapi.yaml index 7831ec6a..e9517a4d 100644 --- a/config/samples/glance_v1beta1_glanceapi.yaml +++ b/config/samples/glance_v1beta1_glanceapi.yaml @@ -5,7 +5,6 @@ metadata: spec: serviceUser: glance serviceAccount: glance - containerImage: quay.io/podified-antelope-centos9/openstack-glance-api:current-podified customServiceConfig: | [DEFAULT] debug = true diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 9cc3d915..45295f39 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -25,6 +25,26 @@ webhooks: resources: - glances sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-glance-openstack-org-v1beta1-glanceapi + failurePolicy: Fail + name: mglanceapi.kb.io + rules: + - apiGroups: + - glance.openstack.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - glanceapis + sideEffects: None --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration @@ -52,3 +72,23 @@ webhooks: resources: - glances sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-glance-openstack-org-v1beta1-glanceapi + failurePolicy: Fail + name: vglanceapi.kb.io + rules: + - apiGroups: + - glance.openstack.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - glanceapis + sideEffects: None diff --git a/hack/clean_local_webhook.sh b/hack/clean_local_webhook.sh index 0d61129f..ad680a58 100755 --- a/hack/clean_local_webhook.sh +++ b/hack/clean_local_webhook.sh @@ -3,3 +3,5 @@ set -ex oc delete validatingwebhookconfiguration/vglance.kb.io --ignore-not-found oc delete mutatingwebhookconfiguration/mglance.kb.io --ignore-not-found +oc delete validatingwebhookconfiguration/vglanceapi.kb.io --ignore-not-found +oc delete mutatingwebhookconfiguration/mglanceapi.kb.io --ignore-not-found diff --git a/hack/configure_local_webhook.sh b/hack/configure_local_webhook.sh index e1a0676a..52f63670 100755 --- a/hack/configure_local_webhook.sh +++ b/hack/configure_local_webhook.sh @@ -83,6 +83,62 @@ webhooks: scope: '*' sideEffects: None timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: vglanceapi.kb.io +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: ${CA_BUNDLE} + url: https://${CRC_IP}:9443/validate-glance-openstack-org-v1beta1-glanceapi + failurePolicy: Fail + matchPolicy: Equivalent + name: vglanceapi.kb.io + objectSelector: {} + rules: + - apiGroups: + - glance.openstack.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - glanceapis + scope: '*' + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mglanceapi.kb.io +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: ${CA_BUNDLE} + url: https://${CRC_IP}:9443/mutate-glance-openstack-org-v1beta1-glanceapi + failurePolicy: Fail + matchPolicy: Equivalent + name: mglanceapi.kb.io + objectSelector: {} + rules: + - apiGroups: + - glance.openstack.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - glanceapis + scope: '*' + sideEffects: None + timeoutSeconds: 10 EOF_CAT oc apply -n openstack -f ${TMPDIR}/patch_webhook_configurations.yaml diff --git a/main.go b/main.go index 383be426..51576ab3 100644 --- a/main.go +++ b/main.go @@ -144,6 +144,10 @@ func main() { setupLog.Error(err, "unable to create webhook", "webhook", "Glance") os.Exit(1) } + if err = (&glancev1.GlanceAPI{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "GlanceAPI") + os.Exit(1) + } checker = mgr.GetWebhookServer().StartedChecker() } //+kubebuilder:scaffold:builder diff --git a/pkg/glance/pvc.go b/pkg/glance/pvc.go index 1659f566..6f234e84 100644 --- a/pkg/glance/pvc.go +++ b/pkg/glance/pvc.go @@ -8,7 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// Pvc - creates and returns a PVC object for a backing store +// GetPvc - creates and returns a PVC object for a backing store func GetPvc(api *glancev1.GlanceAPI, labels map[string]string, pvcType PvcType) corev1.PersistentVolumeClaim { // By default we point to a local storage pvc request // that will be customized in case the pvc is requested diff --git a/pkg/glanceapi/statefulset.go b/pkg/glanceapi/statefulset.go index 287f5a1e..e6a811a6 100644 --- a/pkg/glanceapi/statefulset.go +++ b/pkg/glanceapi/statefulset.go @@ -37,7 +37,7 @@ const ( GlanceAPIHttpdCommand = "/usr/sbin/httpd -DFOREGROUND" ) -// Deployment func +// StatefulSet func func StatefulSet( instance *glancev1.GlanceAPI, configHash string, diff --git a/test/functional/suite_test.go b/test/functional/suite_test.go index 278cd877..42d6a2b2 100644 --- a/test/functional/suite_test.go +++ b/test/functional/suite_test.go @@ -196,6 +196,8 @@ var _ = BeforeSuite(func() { err = (&glancev1.Glance{}).SetupWebhookWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) + err = (&glancev1.GlanceAPI{}).SetupWebhookWithManager(k8sManager) + Expect(err).NotTo(HaveOccurred()) go func() { defer GinkgoRecover() err = k8sManager.Start(ctx)