Skip to content

Commit 2bfa116

Browse files
committed
Add a webhook validation for tls apiOverride
Add webhook to validate TLS apiOverride completeness (CA certificate, certificate, key) before CR is applied. Signed-off-by: Veronika Fisarova <[email protected]>
1 parent 21b29b8 commit 2bfa116

File tree

1 file changed

+68
-12
lines changed

1 file changed

+68
-12
lines changed

apis/core/v1beta1/openstackcontrolplane_webhook.go

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import (
4646
heatv1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1"
4747
horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1"
4848
memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1"
49-
redisv1 "github.com/openstack-k8s-operators/infra-operator/apis/redis/v1beta1"
5049
networkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
50+
redisv1 "github.com/openstack-k8s-operators/infra-operator/apis/redis/v1beta1"
5151
ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1"
5252
manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1"
5353
neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1"
@@ -245,26 +245,32 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad
245245
// Call internal validation logic for individual service operators
246246
if r.Spec.Keystone.Enabled {
247247
errors = append(errors, r.Spec.Keystone.Template.ValidateCreate(basePath.Child("keystone").Child("template"))...)
248+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Keystone.APIOverride.Route, basePath.Child("keystone").Child("apiOverride").Child("route"))...)
248249
}
249250

250251
if r.Spec.Ironic.Enabled {
251252
errors = append(errors, r.Spec.Ironic.Template.ValidateCreate(basePath.Child("ironic").Child("template"))...)
253+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Ironic.APIOverride.Route, basePath.Child("ironic").Child("apiOverride").Child("route"))...)
252254
}
253255

254256
if r.Spec.Nova.Enabled {
255257
errors = append(errors, r.Spec.Nova.Template.ValidateCreate(basePath.Child("nova").Child("template"))...)
258+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Nova.APIOverride.Route, basePath.Child("nova").Child("apiOverride").Child("route"))...)
256259
}
257260

258261
if r.Spec.Placement.Enabled {
259262
errors = append(errors, r.Spec.Placement.Template.ValidateCreate(basePath.Child("placement").Child("template"))...)
263+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Placement.APIOverride.Route, basePath.Child("placement").Child("apiOverride").Child("route"))...)
260264
}
261265

262266
if r.Spec.Barbican.Enabled {
263267
errors = append(errors, r.Spec.Barbican.Template.ValidateCreate(basePath.Child("barbican").Child("template"))...)
268+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Barbican.APIOverride.Route, basePath.Child("barbican").Child("apiOverride").Child("route"))...)
264269
}
265270

266271
if r.Spec.Neutron.Enabled {
267272
errors = append(errors, r.Spec.Neutron.Template.ValidateCreate(basePath.Child("neutron").Child("template"))...)
273+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Neutron.APIOverride.Route, basePath.Child("neutron").Child("apiOverride").Child("route"))...)
268274
}
269275

270276
if r.Spec.Glance.Enabled {
@@ -277,6 +283,11 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad
277283
errors = append(errors, err...)
278284
}
279285
errors = append(errors, r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"))...)
286+
287+
for key, override := range r.Spec.Glance.APIOverride {
288+
overridePath := basePath.Child("glance").Child("apiOverride").Key(key)
289+
errors = append(errors, validateTLSOverrideSpec(&override.Route, overridePath.Child("route"))...)
290+
}
280291
}
281292

282293
if r.Spec.Cinder.Enabled {
@@ -287,28 +298,35 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) (ad
287298
cinderv1.GetCrMaxLengthCorrection(cinderName)) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
288299
errors = append(errors, errs...)
289300
errors = append(errors, r.Spec.Cinder.Template.ValidateCreate(basePath.Child("cinder").Child("template"))...)
301+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Cinder.APIOverride.Route, basePath.Child("cinder").Child("apiOverride").Child("route"))...)
290302
}
291303

292304
if r.Spec.Heat.Enabled {
293305
errors = append(errors, r.Spec.Heat.Template.ValidateCreate(basePath.Child("heat").Child("template"))...)
306+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Heat.APIOverride.Route, basePath.Child("heat").Child("apiOverride").Child("route"))...)
294307
}
295308

296309
if r.Spec.Manila.Enabled {
297310
errors = append(errors, r.Spec.Manila.Template.ValidateCreate(basePath.Child("manila").Child("template"))...)
311+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Manila.APIOverride.Route, basePath.Child("manila").Child("apiOverride").Child("route"))...)
298312
}
299313

300314
if r.Spec.Swift.Enabled {
301315
errors = append(errors, r.Spec.Swift.Template.ValidateCreate(basePath.Child("swift").Child("template"))...)
316+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Swift.ProxyOverride.Route, basePath.Child("swift").Child("apiOverride").Child("route"))...)
302317
}
303318

304319
if r.Spec.Octavia.Enabled {
305320
errors = append(errors, r.Spec.Octavia.Template.ValidateCreate(basePath.Child("octavia").Child("template"))...)
321+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Octavia.APIOverride.Route, basePath.Child("octavia").Child("apiOverride").Child("route"))...)
306322
}
307323

308324
if r.Spec.Designate.Enabled {
309325
errors = append(errors, r.Spec.Designate.Template.ValidateCreate(basePath.Child("designate").Child("template"))...)
326+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Designate.APIOverride.Route, basePath.Child("designate").Child("apiOverride").Child("route"))...)
310327
}
311328

329+
// Validation for remaining services...
312330
if r.Spec.Galera.Enabled {
313331
for key, s := range *r.Spec.Galera.Templates {
314332
warn, err := s.ValidateCreate(basePath.Child("galera").Child("template").Key(key))
@@ -372,41 +390,47 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane
372390
old.Keystone.Template = &keystonev1.KeystoneAPISpecCore{}
373391
}
374392
errors = append(errors, r.Spec.Keystone.Template.ValidateUpdate(*old.Keystone.Template, basePath.Child("keystone").Child("template"))...)
393+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Keystone.APIOverride.Route, basePath.Child("keystone").Child("apiOverride").Child("route"))...)
375394
}
376395

377396
if r.Spec.Ironic.Enabled {
378397
if old.Ironic.Template == nil {
379398
old.Ironic.Template = &ironicv1.IronicSpecCore{}
380399
}
381400
errors = append(errors, r.Spec.Ironic.Template.ValidateUpdate(*old.Ironic.Template, basePath.Child("ironic").Child("template"))...)
401+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Ironic.APIOverride.Route, basePath.Child("ironic").Child("apiOverride").Child("route"))...)
382402
}
383403

384404
if r.Spec.Nova.Enabled {
385405
if old.Nova.Template == nil {
386406
old.Nova.Template = &novav1.NovaSpec{}
387407
}
388408
errors = append(errors, r.Spec.Nova.Template.ValidateUpdate(*old.Nova.Template, basePath.Child("nova").Child("template"))...)
409+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Nova.APIOverride.Route, basePath.Child("nova").Child("apiOverride").Child("route"))...)
389410
}
390411

391412
if r.Spec.Placement.Enabled {
392413
if old.Placement.Template == nil {
393414
old.Placement.Template = &placementv1.PlacementAPISpecCore{}
394415
}
395416
errors = append(errors, r.Spec.Placement.Template.ValidateUpdate(*old.Placement.Template, basePath.Child("placement").Child("template"))...)
417+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Placement.APIOverride.Route, basePath.Child("placement").Child("apiOverride").Child("route"))...)
396418
}
397419

398420
if r.Spec.Barbican.Enabled {
399421
if old.Barbican.Template == nil {
400422
old.Barbican.Template = &barbicanv1.BarbicanSpecCore{}
401423
}
402424
errors = append(errors, r.Spec.Barbican.Template.ValidateUpdate(*old.Barbican.Template, basePath.Child("barbican").Child("template"))...)
425+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Barbican.APIOverride.Route, basePath.Child("barbican").Child("apiOverride").Child("route"))...)
403426
}
404427

405428
if r.Spec.Neutron.Enabled {
406429
if old.Neutron.Template == nil {
407430
old.Neutron.Template = &neutronv1.NeutronAPISpecCore{}
408431
}
409432
errors = append(errors, r.Spec.Neutron.Template.ValidateUpdate(*old.Neutron.Template, basePath.Child("neutron").Child("template"))...)
433+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Neutron.APIOverride.Route, basePath.Child("neutron").Child("apiOverride").Child("route"))...)
410434
}
411435

412436
if r.Spec.Glance.Enabled {
@@ -422,6 +446,11 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane
422446
errors = append(errors, err...)
423447
}
424448
errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"))...)
449+
450+
for key, override := range r.Spec.Glance.APIOverride {
451+
overridePath := basePath.Child("glance").Child("apiOverride").Key(key)
452+
errors = append(errors, validateTLSOverrideSpec(&override.Route, overridePath.Child("route"))...)
453+
}
425454
}
426455

427456
if r.Spec.Cinder.Enabled {
@@ -435,41 +464,47 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane
435464
cinderv1.GetCrMaxLengthCorrection(cinderName)) // omit issue with statefulset pod label "controller-revision-hash": "<statefulset_name>-<hash>"
436465
errors = append(errors, errs...)
437466
errors = append(errors, r.Spec.Cinder.Template.ValidateUpdate(*old.Cinder.Template, basePath.Child("cinder").Child("template"))...)
467+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Cinder.APIOverride.Route, basePath.Child("cinder").Child("apiOverride").Child("route"))...)
438468
}
439469

440470
if r.Spec.Heat.Enabled {
441471
if old.Heat.Template == nil {
442472
old.Heat.Template = &heatv1.HeatSpecCore{}
443473
}
444474
errors = append(errors, r.Spec.Heat.Template.ValidateUpdate(*old.Heat.Template, basePath.Child("heat").Child("template"))...)
475+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Heat.APIOverride.Route, basePath.Child("heat").Child("apiOverride").Child("route"))...)
445476
}
446477

447478
if r.Spec.Manila.Enabled {
448479
if old.Manila.Template == nil {
449480
old.Manila.Template = &manilav1.ManilaSpecCore{}
450481
}
451482
errors = append(errors, r.Spec.Manila.Template.ValidateUpdate(*old.Manila.Template, basePath.Child("manila").Child("template"))...)
483+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Manila.APIOverride.Route, basePath.Child("manila").Child("apiOverride").Child("route"))...)
452484
}
453485

454486
if r.Spec.Swift.Enabled {
455487
if old.Swift.Template == nil {
456488
old.Swift.Template = &swiftv1.SwiftSpecCore{}
457489
}
458490
errors = append(errors, r.Spec.Swift.Template.ValidateUpdate(*old.Swift.Template, basePath.Child("swift").Child("template"))...)
491+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Swift.ProxyOverride.Route, basePath.Child("swift").Child("apiOverride").Child("route"))...)
459492
}
460493

461494
if r.Spec.Octavia.Enabled {
462495
if old.Octavia.Template == nil {
463496
old.Octavia.Template = &octaviav1.OctaviaSpecCore{}
464497
}
465498
errors = append(errors, r.Spec.Octavia.Template.ValidateUpdate(*old.Octavia.Template, basePath.Child("octavia").Child("template"))...)
499+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Octavia.APIOverride.Route, basePath.Child("octavia").Child("apiOverride").Child("route"))...)
466500
}
467501

468502
if r.Spec.Designate.Enabled {
469503
if old.Designate.Template == nil {
470504
old.Designate.Template = &designatev1.DesignateSpecCore{}
471505
}
472506
errors = append(errors, r.Spec.Designate.Template.ValidateUpdate(*old.Designate.Template, basePath.Child("designate").Child("template"))...)
507+
errors = append(errors, validateTLSOverrideSpec(&r.Spec.Designate.APIOverride.Route, basePath.Child("designate").Child("apiOverride").Child("route"))...)
473508
}
474509

475510
if r.Spec.Memcached.Enabled {
@@ -875,17 +910,17 @@ func (r *OpenStackControlPlane) DefaultServices() {
875910
}
876911

877912
// Redis
878-
if r.Spec.Redis.Enabled || r.Spec.Redis.Templates != nil {
879-
if r.Spec.Redis.Templates == nil {
880-
r.Spec.Redis.Templates = ptr.To(map[string]redisv1.RedisSpecCore{})
881-
}
882-
883-
for key, template := range *r.Spec.Redis.Templates {
884-
template.Default()
885-
// By-value copy, need to update
886-
(*r.Spec.Redis.Templates)[key] = template
887-
}
888-
}
913+
if r.Spec.Redis.Enabled || r.Spec.Redis.Templates != nil {
914+
if r.Spec.Redis.Templates == nil {
915+
r.Spec.Redis.Templates = ptr.To(map[string]redisv1.RedisSpecCore{})
916+
}
917+
918+
for key, template := range *r.Spec.Redis.Templates {
919+
template.Default()
920+
// By-value copy, need to update
921+
(*r.Spec.Redis.Templates)[key] = template
922+
}
923+
}
889924

890925
}
891926

@@ -902,3 +937,24 @@ func (r *OpenStackControlPlane) DefaultLabel() {
902937
r.Labels[typeLabel] = ""
903938
}
904939
}
940+
941+
// ValidateTLSData checks if the TLS data in the apiOverride are complete
942+
func validateTLSOverrideSpec(override **route.OverrideSpec, basePath *field.Path) field.ErrorList {
943+
var allErrs field.ErrorList
944+
945+
if *override == nil {
946+
return allErrs
947+
}
948+
949+
tlsSpec := (*override).Spec
950+
if tlsSpec != nil && tlsSpec.TLS != nil {
951+
if tlsSpec.TLS.Certificate == "" {
952+
allErrs = append(allErrs, field.Required(basePath.Child("tls").Child("certificate"), "Certificate is required"))
953+
}
954+
if tlsSpec.TLS.Key == "" {
955+
allErrs = append(allErrs, field.Required(basePath.Child("tls").Child("key"), "Key is required"))
956+
}
957+
}
958+
959+
return allErrs
960+
}

0 commit comments

Comments
 (0)