Skip to content

Commit 12068df

Browse files
committed
Consume Topology CR by reference
This patch provides more granular control over Pod placement and scheduling through the Topology CR integration introduced in [1]. In particular it provides: - a new API parameter (TopologyRef) defined for each Component that allows to reference an existing Topology CRs in the same namespace - the operator logic that retrieves and processes the referenced Topology CR through the functions provided by lib-common [2] - enhanced StatefulSet and Deployment configuration that incorporates the processed Topology Note that webhooks are in place to prevent referencing a Topology from a different namespace (which is not a supported scenario). Signed-off-by: Francesco Pantano <[email protected]>
1 parent 5d5c280 commit 12068df

23 files changed

+607
-43
lines changed

api/bases/swift.openstack.org_swiftproxies.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,23 @@ spec:
308308
bundle file
309309
type: string
310310
type: object
311+
topologyRef:
312+
description: |-
313+
TopologyRef to apply the Topology defined by the associated CR referenced
314+
by name
315+
properties:
316+
name:
317+
description: Name - The Topology CR name that the Service references
318+
type: string
319+
namespace:
320+
description: |-
321+
Namespace - The Namespace to fetch the Topology CR referenced
322+
NOTE: Namespace currently points by default to the same namespace where
323+
the Service is deployed. Customizing the namespace is not supported and
324+
webhooks prevent editing this field to a value different from the
325+
current project
326+
type: string
327+
type: object
311328
required:
312329
- containerImageProxy
313330
- memcachedInstance
@@ -366,6 +383,9 @@ spec:
366383
type: string
367384
description: Map of hashes to track e.g. job status
368385
type: object
386+
lastAppliedTopology:
387+
description: LastAppliedTopology - the last applied Topology
388+
type: string
369389
networkAttachments:
370390
additionalProperties:
371391
items:

api/bases/swift.openstack.org_swifts.yaml

+53
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,24 @@ spec:
334334
a pre-created bundle file
335335
type: string
336336
type: object
337+
topologyRef:
338+
description: |-
339+
TopologyRef to apply the Topology defined by the associated CR referenced
340+
by name
341+
properties:
342+
name:
343+
description: Name - The Topology CR name that the Service
344+
references
345+
type: string
346+
namespace:
347+
description: |-
348+
Namespace - The Namespace to fetch the Topology CR referenced
349+
NOTE: Namespace currently points by default to the same namespace where
350+
the Service is deployed. Customizing the namespace is not supported and
351+
webhooks prevent editing this field to a value different from the
352+
current project
353+
type: string
354+
type: object
337355
required:
338356
- containerImageProxy
339357
- memcachedInstance
@@ -444,6 +462,24 @@ spec:
444462
default: 10Gi
445463
description: Minimum size for Swift PVs
446464
type: string
465+
topologyRef:
466+
description: |-
467+
TopologyRef to apply the Topology defined by the associated CR referenced
468+
by name
469+
properties:
470+
name:
471+
description: Name - The Topology CR name that the Service
472+
references
473+
type: string
474+
namespace:
475+
description: |-
476+
Namespace - The Namespace to fetch the Topology CR referenced
477+
NOTE: Namespace currently points by default to the same namespace where
478+
the Service is deployed. Customizing the namespace is not supported and
479+
webhooks prevent editing this field to a value different from the
480+
current project
481+
type: string
482+
type: object
447483
required:
448484
- containerImageAccount
449485
- containerImageContainer
@@ -454,6 +490,23 @@ spec:
454490
- storageClass
455491
- storageRequest
456492
type: object
493+
topologyRef:
494+
description: |-
495+
TopologyRef to apply the Topology defined by the associated CR referenced
496+
by name
497+
properties:
498+
name:
499+
description: Name - The Topology CR name that the Service references
500+
type: string
501+
namespace:
502+
description: |-
503+
Namespace - The Namespace to fetch the Topology CR referenced
504+
NOTE: Namespace currently points by default to the same namespace where
505+
the Service is deployed. Customizing the namespace is not supported and
506+
webhooks prevent editing this field to a value different from the
507+
current project
508+
type: string
509+
type: object
457510
required:
458511
- memcachedInstance
459512
- storageClass

api/bases/swift.openstack.org_swiftstorages.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ spec:
104104
default: 10Gi
105105
description: Minimum size for Swift PVs
106106
type: string
107+
topologyRef:
108+
description: |-
109+
TopologyRef to apply the Topology defined by the associated CR referenced
110+
by name
111+
properties:
112+
name:
113+
description: Name - The Topology CR name that the Service references
114+
type: string
115+
namespace:
116+
description: |-
117+
Namespace - The Namespace to fetch the Topology CR referenced
118+
NOTE: Namespace currently points by default to the same namespace where
119+
the Service is deployed. Customizing the namespace is not supported and
120+
webhooks prevent editing this field to a value different from the
121+
current project
122+
type: string
123+
type: object
107124
required:
108125
- containerImageAccount
109126
- containerImageContainer
@@ -164,6 +181,9 @@ spec:
164181
type: string
165182
description: Map of hashes to track e.g. job status
166183
type: object
184+
lastAppliedTopology:
185+
description: LastAppliedTopology - the last applied Topology
186+
type: string
167187
networkAttachments:
168188
additionalProperties:
169189
items:

api/go.mod

+7-7
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ go 1.21
55
require (
66
github.com/onsi/ginkgo/v2 v2.20.1
77
github.com/onsi/gomega v1.34.1
8-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250124131400-f604bec9afd2
9-
k8s.io/api v0.29.12
10-
k8s.io/apimachinery v0.29.12
11-
k8s.io/client-go v0.29.12
8+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250123115751-98853871de94
9+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250128130522-53b65fcdadca
10+
k8s.io/api v0.29.13
11+
k8s.io/apimachinery v0.29.13
12+
k8s.io/client-go v0.29.13
1213
sigs.k8s.io/controller-runtime v0.17.6
1314
)
1415

@@ -17,7 +18,6 @@ require (
1718
github.com/cespare/xxhash/v2 v2.2.0 // indirect
1819
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
1920
github.com/emicklei/go-restful/v3 v3.12.0 // indirect
20-
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
2121
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
2222
github.com/fsnotify/fsnotify v1.7.0 // indirect
2323
github.com/go-logr/logr v1.4.2 // indirect
@@ -65,8 +65,8 @@ require (
6565
gopkg.in/inf.v0 v0.9.1 // indirect
6666
gopkg.in/yaml.v2 v2.4.0 // indirect
6767
gopkg.in/yaml.v3 v3.0.1 // indirect
68-
k8s.io/apiextensions-apiserver v0.29.12 // indirect
69-
k8s.io/component-base v0.29.12 // indirect
68+
k8s.io/apiextensions-apiserver v0.29.13 // indirect
69+
k8s.io/component-base v0.29.13 // indirect
7070
k8s.io/klog/v2 v2.120.1 // indirect
7171
k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect
7272
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect

api/go.sum

+14-12
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo
7272
github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
7373
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
7474
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
75-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250124131400-f604bec9afd2 h1:hN6XaJS6UPGjB/0aGt9LKzXYOTGAyDjpL+vMEeVzpBI=
76-
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250124131400-f604bec9afd2/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs=
75+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250123115751-98853871de94 h1:qOSjHqncEAJeBBCITKqq3shZMuGbDC+YBiRnGIoMnoI=
76+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250123115751-98853871de94/go.mod h1:TDaE7BVQvJwJGFm33R6xcPTeF8LKAnMh+a1ho+YqJHs=
77+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250128130522-53b65fcdadca h1:VzIM4LLWAJX9eDC2XvwLvaFNP7BnekNTQ9HUb6C/jbw=
78+
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250128130522-53b65fcdadca/go.mod h1:KxnNSUk15llkKTSq/bQEE7pnc0IMk44fxhoBRpimMa8=
7779
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
7880
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
7981
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -177,16 +179,16 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
177179
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
178180
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
179181
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
180-
k8s.io/api v0.29.12 h1:SsEEMtFupOAt3pAAtAz0PDu+54g3L5rwbSCi0xQzAJM=
181-
k8s.io/api v0.29.12/go.mod h1:QFwqOP+7LNoAG1RI3vKAFxjKSLQTCamcPzAQ0Z/Yhuk=
182-
k8s.io/apiextensions-apiserver v0.29.12 h1:xoQfYPwAzfcoH/MVuQiSPTWmFrmblvYbUMODpfYyyw8=
183-
k8s.io/apiextensions-apiserver v0.29.12/go.mod h1:L1GHiWK2bkYrZOkFtChfkVpPUh9Ogr6gmShM28Yhqk0=
184-
k8s.io/apimachinery v0.29.12 h1:k6OdfK9xaNANQvWkl1pSICJGLjB4jSuJ3gGP9hBKOhE=
185-
k8s.io/apimachinery v0.29.12/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
186-
k8s.io/client-go v0.29.12 h1:PjwJXavmpAqOWBRy4U5V/g3JQBpclIHEn5dvfTfsY+w=
187-
k8s.io/client-go v0.29.12/go.mod h1:hRHG6tAKxaLVKF5SlMqgXrbqPEoUcUpJGFFrC3jU69A=
188-
k8s.io/component-base v0.29.12 h1:NuFNzBSF3Iopih6VpvYmtjpdN1MLc9PcByl60fcJ0tQ=
189-
k8s.io/component-base v0.29.12/go.mod h1:YHua3E5Lvnva6dXqGqiuRj8CxhBw7g6KgYV/dcS7LBU=
182+
k8s.io/api v0.29.13 h1:VkMIbjJw1t2VgTatg8ggzI93LOfFa8z8SzAYzXtWuEg=
183+
k8s.io/api v0.29.13/go.mod h1:fBWhXqqE25b46PZEVA2DXN2EuhNg1ZT3VRyb5JitLG8=
184+
k8s.io/apiextensions-apiserver v0.29.13 h1:3xsTohNwndx4NJjgqoi5VuBPWeG4yY4VXOF62ugXvhU=
185+
k8s.io/apiextensions-apiserver v0.29.13/go.mod h1:plxNh3qMNsiMo4svQtkVp47n+2/rwm/c8FTJYR6rikQ=
186+
k8s.io/apimachinery v0.29.13 h1:a7I4uQtlfaL+UTRGFhl8lLd2nHBR7qt+axhQLtpLYMg=
187+
k8s.io/apimachinery v0.29.13/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
188+
k8s.io/client-go v0.29.13 h1:M2scR9NWGlzI2YoIxTgwx2N3OA+dXqN87zsM4tvewmA=
189+
k8s.io/client-go v0.29.13/go.mod h1:BBzF0Pr78Y8DM20j22E6tOMwTBpFaKnSnn6N0pNe4VE=
190+
k8s.io/component-base v0.29.13 h1:RbksXVzXYYYvmOCArMKIkxna5eTt6DjI4Zy/4H3JFLo=
191+
k8s.io/component-base v0.29.13/go.mod h1:pjMLwLNxDg0JvXRc69GIFUEawiZEtDzm0yAJ5+Naj9s=
190192
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
191193
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
192194
k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 h1:qVoMaQV5t62UUvHe16Q3eb2c5HPzLHYzsi0Tu/xLndo=

api/v1beta1/swift_types.go

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package v1beta1
1919
import (
2020
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2121
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
22+
"github.com/openstack-k8s-operators/lib-common/modules/common/topology"
2223
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2324
)
2425

@@ -85,6 +86,11 @@ type SwiftSpecBase struct {
8586
// +kubebuilder:validation:Optional
8687
// NodeSelector to target subset of worker nodes running this service
8788
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
89+
90+
// +kubebuilder:validation:Optional
91+
// TopologyRef to apply the Topology defined by the associated CR referenced
92+
// by name
93+
TopologyRef *topology.TopoRef `json:"topologyRef,omitempty"`
8894
}
8995

9096
// SwiftStatus defines the observed state of Swift

api/v1beta1/swift_webhook.go

+40
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121

2222
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
23+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2324
apierrors "k8s.io/apimachinery/pkg/api/errors"
2425
"k8s.io/apimachinery/pkg/runtime"
2526
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -117,6 +118,10 @@ func (r *Swift) ValidateCreate() (admission.Warnings, error) {
117118

118119
var allErrs field.ErrorList
119120
basePath := field.NewPath("spec")
121+
122+
// validate TopologyRef namespace
123+
allErrs = r.Spec.ValidateSwiftTopology(basePath, r.Namespace)
124+
120125
if err := r.Spec.ValidateCreate(basePath); err != nil {
121126
allErrs = append(allErrs, err...)
122127
}
@@ -166,6 +171,9 @@ func (r *Swift) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
166171
var allErrs field.ErrorList
167172
basePath := field.NewPath("spec")
168173

174+
// validate TopologyRef namespace
175+
allErrs = r.Spec.ValidateSwiftTopology(basePath, r.Namespace)
176+
169177
if err := r.Spec.ValidateUpdate(oldSwift.Spec, basePath); err != nil {
170178
allErrs = append(allErrs, err...)
171179
}
@@ -248,3 +256,35 @@ func (r *Swift) ValidateDelete() (admission.Warnings, error) {
248256
// TODO(user): fill in your validation logic upon object deletion.
249257
return nil, nil
250258
}
259+
260+
// ValidateSwiftTopology - Returns an ErrorList if the Topology is referenced
261+
// on a different namespace
262+
func (spec *SwiftSpec) ValidateSwiftTopology(basePath *field.Path, namespace string) field.ErrorList {
263+
var allErrs field.ErrorList
264+
265+
// When a TopologyRef CR is referenced, fail if a different Namespace is
266+
// referenced because is not supported
267+
if spec.TopologyRef != nil {
268+
if err := topologyv1.ValidateTopologyNamespace(spec.TopologyRef.Namespace, *basePath, namespace); err != nil {
269+
allErrs = append(allErrs, err)
270+
}
271+
}
272+
273+
// When a TopologyRef CR is referenced with an override to SwiftProxy, fail
274+
// if a different Namespace is referenced because not supported
275+
if spec.SwiftProxy.TopologyRef != nil {
276+
if err := topologyv1.ValidateTopologyNamespace(spec.SwiftProxy.TopologyRef.Namespace, *basePath, namespace); err != nil {
277+
allErrs = append(allErrs, err)
278+
}
279+
}
280+
281+
// When a TopologyRef CR is referenced with an override to SwiftStorage
282+
// fail if a different Namespace is referenced because not supported
283+
if spec.SwiftStorage.TopologyRef != nil {
284+
if err := topologyv1.ValidateTopologyNamespace(spec.SwiftStorage.TopologyRef.Namespace, *basePath, namespace); err != nil {
285+
allErrs = append(allErrs, err)
286+
}
287+
}
288+
289+
return allErrs
290+
}

api/v1beta1/swiftproxy_types.go

+9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package v1beta1
1919
import (
2020
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2121
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
22+
"github.com/openstack-k8s-operators/lib-common/modules/common/topology"
2223
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
)
@@ -105,6 +106,11 @@ type SwiftProxySpecCore struct {
105106
// +kubebuilder:validation:Optional
106107
// NodeSelector to target subset of worker nodes running this service
107108
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
109+
110+
// +kubebuilder:validation:Optional
111+
// TopologyRef to apply the Topology defined by the associated CR referenced
112+
// by name
113+
TopologyRef *topology.TopoRef `json:"topologyRef,omitempty"`
108114
}
109115

110116
// ProxyOverrideSpec to override the generated manifest of several child resources.
@@ -136,6 +142,9 @@ type SwiftProxyStatus struct {
136142
// then the controller has not processed the latest changes injected by
137143
// the openstack-operator in the top-level CR (e.g. the ContainerImage)
138144
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
145+
146+
// LastAppliedTopology - the last applied Topology
147+
LastAppliedTopology string `json:"lastAppliedTopology,omitempty"`
139148
}
140149

141150
//+kubebuilder:object:root=true

api/v1beta1/swiftstorage_types.go

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package v1beta1
1818

1919
import (
2020
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
21+
"github.com/openstack-k8s-operators/lib-common/modules/common/topology"
2122
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2223
)
2324

@@ -83,6 +84,11 @@ type SwiftStorageSpecCore struct {
8384
// +kubebuilder:validation:Optional
8485
// NodeSelector to target subset of worker nodes running this service
8586
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
87+
88+
// +kubebuilder:validation:Optional
89+
// TopologyRef to apply the Topology defined by the associated CR referenced
90+
// by name
91+
TopologyRef *topology.TopoRef `json:"topologyRef,omitempty"`
8692
}
8793

8894
// SwiftStorageStatus defines the observed state of SwiftStorage
@@ -104,6 +110,9 @@ type SwiftStorageStatus struct {
104110
// then the controller has not processed the latest changes injected by
105111
// the openstack-operator in the top-level CR (e.g. the ContainerImage)
106112
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
113+
114+
// LastAppliedTopology - the last applied Topology
115+
LastAppliedTopology string `json:"lastAppliedTopology,omitempty"`
107116
}
108117

109118
//+kubebuilder:object:root=true

0 commit comments

Comments
 (0)