Skip to content

Commit 7c2910e

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 infra-operator. 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 infra-operator - enhanced StatefulSet and deployment configuration that incorporates the processed Topology - a set of kuttl tests to double check the lifecycle (add/update/override/remove) of the resulting Deployments and DaemonSet when a Topology is referenced 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 5d76e7c commit 7c2910e

40 files changed

+925
-16
lines changed

api/bases/telemetry.openstack.org_autoscalings.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,24 @@ spec:
345345
a pre-created bundle file
346346
type: string
347347
type: object
348+
topologyRef:
349+
description: |-
350+
TopologyRef to apply the Topology defined by the associated CR referenced
351+
by name
352+
properties:
353+
name:
354+
description: Name - The Topology CR name that the Service
355+
references
356+
type: string
357+
namespace:
358+
description: |-
359+
Namespace - The Namespace to fetch the Topology CR referenced
360+
NOTE: Namespace currently points by default to the same namespace where
361+
the Service is deployed. Customizing the namespace is not supported and
362+
webhooks prevent editing this field to a value different from the
363+
current project
364+
type: string
365+
type: object
348366
required:
349367
- apiImage
350368
- databaseInstance
@@ -449,6 +467,9 @@ spec:
449467
type: string
450468
description: Map of hashes to track e.g. job status
451469
type: object
470+
lastAppliedTopology:
471+
description: LastAppliedTopology - the last applied Topology
472+
type: string
452473
networks:
453474
description: Networks in addtion to the cluster network, the service
454475
is attached to

api/bases/telemetry.openstack.org_ceilometers.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,23 @@ spec:
242242
description: SecretName - holding the cert, key for the service
243243
type: string
244244
type: object
245+
topologyRef:
246+
description: |-
247+
TopologyRef to apply the Topology defined by the associated CR referenced
248+
by name
249+
properties:
250+
name:
251+
description: Name - The Topology CR name that the Service references
252+
type: string
253+
namespace:
254+
description: |-
255+
Namespace - The Namespace to fetch the Topology CR referenced
256+
NOTE: Namespace currently points by default to the same namespace where
257+
the Service is deployed. Customizing the namespace is not supported and
258+
webhooks prevent editing this field to a value different from the
259+
current project
260+
type: string
261+
type: object
245262
required:
246263
- centralImage
247264
- computeImage
@@ -310,6 +327,9 @@ spec:
310327
description: ReadyCount of kube-state-metrics instances
311328
format: int32
312329
type: integer
330+
lastAppliedTopology:
331+
description: LastAppliedTopology - the last applied Topology
332+
type: string
313333
mysqldExporterExportedGaleras:
314334
description: List of galera CRs, which are being exported with mysqld_exporter
315335
items:

api/bases/telemetry.openstack.org_telemetries.yaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,24 @@ spec:
348348
in a pre-created bundle file
349349
type: string
350350
type: object
351+
topologyRef:
352+
description: |-
353+
TopologyRef to apply the Topology defined by the associated CR referenced
354+
by name
355+
properties:
356+
name:
357+
description: Name - The Topology CR name that the Service
358+
references
359+
type: string
360+
namespace:
361+
description: |-
362+
Namespace - The Namespace to fetch the Topology CR referenced
363+
NOTE: Namespace currently points by default to the same namespace where
364+
the Service is deployed. Customizing the namespace is not supported and
365+
webhooks prevent editing this field to a value different from the
366+
current project
367+
type: string
368+
type: object
351369
required:
352370
- apiImage
353371
- databaseInstance
@@ -538,6 +556,24 @@ spec:
538556
description: SecretName - holding the cert, key for the service
539557
type: string
540558
type: object
559+
topologyRef:
560+
description: |-
561+
TopologyRef to apply the Topology defined by the associated CR referenced
562+
by name
563+
properties:
564+
name:
565+
description: Name - The Topology CR name that the Service
566+
references
567+
type: string
568+
namespace:
569+
description: |-
570+
Namespace - The Namespace to fetch the Topology CR referenced
571+
NOTE: Namespace currently points by default to the same namespace where
572+
the Service is deployed. Customizing the namespace is not supported and
573+
webhooks prevent editing this field to a value different from the
574+
current project
575+
type: string
576+
type: object
541577
required:
542578
- centralImage
543579
- computeImage
@@ -1894,6 +1930,23 @@ spec:
18941930
description: NodeSelector to target subset of worker nodes running
18951931
this service
18961932
type: object
1933+
topologyRef:
1934+
description: |-
1935+
TopologyRef to apply the Topology defined by the associated CR referenced
1936+
by name
1937+
properties:
1938+
name:
1939+
description: Name - The Topology CR name that the Service references
1940+
type: string
1941+
namespace:
1942+
description: |-
1943+
Namespace - The Namespace to fetch the Topology CR referenced
1944+
NOTE: Namespace currently points by default to the same namespace where
1945+
the Service is deployed. Customizing the namespace is not supported and
1946+
webhooks prevent editing this field to a value different from the
1947+
current project
1948+
type: string
1949+
type: object
18971950
type: object
18981951
status:
18991952
description: TelemetryStatus defines the observed state of Telemetry
@@ -1945,6 +1998,9 @@ spec:
19451998
type: string
19461999
description: Map of hashes to track e.g. job status
19472000
type: object
2001+
lastAppliedTopology:
2002+
description: LastAppliedTopology - the last applied Topology
2003+
type: string
19482004
observedGeneration:
19492005
description: |-
19502006
ObservedGeneration - the most recent generation observed for this

api/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ 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/infra-operator/apis v0.5.1-0.20250204091142-ae8379c31edb
8+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250213131341-8e63f078f923
99
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250205143454-43504d7ad19a
1010
github.com/rhobs/observability-operator v0.3.1
1111
k8s.io/api v0.29.13

api/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ 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/infra-operator/apis v0.5.1-0.20250204091142-ae8379c31edb h1:SedlzLahRyzctVTXzVrpmjui78A7Z0g8V1cmPBoQzYY=
76-
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250204091142-ae8379c31edb/go.mod h1:TDaE7BVQvJwJGFm33R6xcPTeF8LKAnMh+a1ho+YqJHs=
75+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250213131341-8e63f078f923 h1:PpGup24Ri4sgw8UNyaEENy16dUHLIo8i4bpj8hLQWoU=
76+
github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20250213131341-8e63f078f923/go.mod h1:kkjcOSZ7jkHbVzxJd0nDQzjB+vqafuAMgSf7AnEXydw=
7777
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250205143454-43504d7ad19a h1:3LuUgB85VxGD6lmVOeZelYEASmytkrzaudU014PN7xw=
7878
github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20250205143454-43504d7ad19a/go.mod h1:KxnNSUk15llkKTSq/bQEE7pnc0IMk44fxhoBRpimMa8=
7979
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

api/v1beta1/autoscaling_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
2222
corev1 "k8s.io/api/core/v1"
2323
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2425

2526
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
2627
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
@@ -131,6 +132,11 @@ type AodhCore struct {
131132
// +kubebuilder:validation:Optional
132133
// NodeSelector to target subset of worker nodes running this service
133134
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
135+
136+
// +kubebuilder:validation:Optional
137+
// TopologyRef to apply the Topology defined by the associated CR referenced
138+
// by name
139+
TopologyRef *topologyv1.TopoRef `json:"topologyRef,omitempty"`
134140
}
135141

136142
// APIOverrideSpec to override the generated manifest of several child resources.
@@ -217,6 +223,9 @@ type AutoscalingStatus struct {
217223
// then the controller has not processed the latest changes injected by
218224
// the openstack-operator in the top-level CR (e.g. the ContainerImage)
219225
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
226+
227+
// LastAppliedTopology - the last applied Topology
228+
LastAppliedTopology string `json:"lastAppliedTopology,omitempty"`
220229
}
221230

222231
//+kubebuilder:object:root=true

api/v1beta1/ceilometer_types.go

Lines changed: 9 additions & 0 deletions
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
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2223

2324
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
2425
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
@@ -149,6 +150,11 @@ type CeilometerSpecCore struct {
149150
// +kubebuilder:validation:Optional
150151
// NodeSelector to target subset of worker nodes running this service
151152
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
153+
154+
// +kubebuilder:validation:Optional
155+
// TopologyRef to apply the Topology defined by the associated CR referenced
156+
// by name
157+
TopologyRef *topologyv1.TopoRef `json:"topologyRef,omitempty"`
152158
}
153159

154160
// CeilometerStatus defines the observed state of Ceilometer
@@ -189,6 +195,9 @@ type CeilometerStatus struct {
189195

190196
// Map of hashes to track e.g. job status
191197
KSMHash map[string]string `json:"ksmHash,omitempty"`
198+
199+
// LastAppliedTopology - the last applied Topology
200+
LastAppliedTopology string `json:"lastAppliedTopology,omitempty"`
192201
}
193202

194203
// NOTE(mmagr): remove KSMStatus with API version increment

api/v1beta1/telemetry_types.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2323
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
24+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2425
)
2526

2627
// PasswordsSelector to identify the Service password from the Secret
@@ -75,6 +76,11 @@ type TelemetrySpecBase struct {
7576
// +kubebuilder:validation:Optional
7677
// NodeSelector to target subset of worker nodes running this service
7778
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
79+
80+
// +kubebuilder:validation:Optional
81+
// TopologyRef to apply the Topology defined by the associated CR referenced
82+
// by name
83+
TopologyRef *topologyv1.TopoRef `json:"topologyRef,omitempty"`
7884
}
7985

8086
// CeilometerSection defines the desired state of the ceilometer service
@@ -174,6 +180,9 @@ type TelemetryStatus struct {
174180
// then the controller has not processed the latest changes injected by
175181
// the openstack-operator in the top-level CR (e.g. the ContainerImage)
176182
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
183+
184+
// LastAppliedTopology - the last applied Topology
185+
LastAppliedTopology string `json:"lastAppliedTopology,omitempty"`
177186
}
178187

179188
//+kubebuilder:object:root=true

api/v1beta1/telemetry_webhook.go

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import (
2525
logf "sigs.k8s.io/controller-runtime/pkg/log"
2626
"sigs.k8s.io/controller-runtime/pkg/webhook"
2727
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
28+
apierrors "k8s.io/apimachinery/pkg/api/errors"
29+
"k8s.io/apimachinery/pkg/runtime/schema"
30+
"k8s.io/apimachinery/pkg/util/validation/field"
31+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2832
)
2933

3034
// TelemetryDefaults -
@@ -126,16 +130,32 @@ var _ webhook.Validator = &Telemetry{}
126130
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
127131
func (r *Telemetry) ValidateCreate() (admission.Warnings, error) {
128132
telemetrylog.Info("validate create", "name", r.Name)
133+
var allErrs field.ErrorList
134+
basePath := field.NewPath("spec")
135+
136+
allErrs = r.Spec.ValidateTelemetryTopology(basePath, r.Namespace)
137+
if len(allErrs) != 0 {
138+
return nil, apierrors.NewInvalid(
139+
schema.GroupKind{Group: "telemetry.openstack.org", Kind: "Telemetry"},
140+
r.Name, allErrs)
141+
}
129142

130-
// TODO(user): fill in your validation logic upon object creation.
131143
return nil, nil
132144
}
133145

134146
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
135147
func (r *Telemetry) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
136148
telemetrylog.Info("validate update", "name", r.Name)
137149

138-
// TODO(user): fill in your validation logic upon object update.
150+
var allErrs field.ErrorList
151+
basePath := field.NewPath("spec")
152+
153+
allErrs = r.Spec.ValidateTelemetryTopology(basePath, r.Namespace)
154+
if len(allErrs) != 0 {
155+
return nil, apierrors.NewInvalid(
156+
schema.GroupKind{Group: "telemetry.openstack.org", Kind: "Telemetry"},
157+
r.Name, allErrs)
158+
}
139159
return nil, nil
140160
}
141161

@@ -146,3 +166,35 @@ func (r *Telemetry) ValidateDelete() (admission.Warnings, error) {
146166
// TODO(user): fill in your validation logic upon object deletion.
147167
return nil, nil
148168
}
169+
170+
// ValidateTelemetryTopology - Returns an ErrorList if the Topology is referenced
171+
// on a different namespace
172+
func (spec *TelemetrySpec) ValidateTelemetryTopology(basePath *field.Path, namespace string) field.ErrorList {
173+
var allErrs field.ErrorList
174+
175+
// When a TopologyRef CR is referenced, fail if a different Namespace is
176+
// referenced because is not supported
177+
if spec.TopologyRef != nil {
178+
if err := topologyv1.ValidateTopologyNamespace(spec.TopologyRef.Namespace, *basePath, namespace); err != nil {
179+
allErrs = append(allErrs, err)
180+
}
181+
}
182+
183+
// When a TopologyRef CR is referenced with an override to Aodh, fail
184+
// if a different Namespace is referenced because not supported
185+
if spec.Autoscaling.Aodh.TopologyRef != nil {
186+
if err := topologyv1.ValidateTopologyNamespace(spec.Autoscaling.Aodh.TopologyRef.Namespace, *basePath, namespace); err != nil {
187+
allErrs = append(allErrs, err)
188+
}
189+
}
190+
191+
// When a TopologyRef CR is referenced with an override to Ceilometer,
192+
// fail if a different Namespace is referenced because not supported
193+
if spec.Ceilometer.TopologyRef != nil {
194+
if err := topologyv1.ValidateTopologyNamespace(spec.Ceilometer.TopologyRef.Namespace, *basePath, namespace); err != nil {
195+
allErrs = append(allErrs, err)
196+
}
197+
}
198+
199+
return allErrs
200+
}

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)