Skip to content

Commit b69a59c

Browse files
committed
Merge placement codebase into nova-operator
This change merges placement-operator codebase into nova-operator. Closes: OSPRH-14957
1 parent 563e49d commit b69a59c

File tree

67 files changed

+7196
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+7196
-2
lines changed

PROJECT

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,17 @@ resources:
116116
defaulting: true
117117
validation: true
118118
webhookVersion: v1
119+
- api:
120+
crdVersion: v1
121+
namespaced: true
122+
controller: true
123+
domain: openstack.org
124+
group: placement
125+
kind: PlacementAPI
126+
path: github.com/openstack-k8s-operators/nova-operator/apis/placement/v1beta1
127+
version: v1beta1
128+
webhooks:
129+
defaulting: true
130+
validation: true
131+
webhookVersion: v1
119132
version: "3"

apis/bases/placement.openstack.org_placementapis.yaml

Lines changed: 490 additions & 0 deletions
Large diffs are not rendered by default.

apis/go.mod

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ go 1.21
44

55
require (
66
github.com/google/go-cmp v0.7.0
7+
github.com/onsi/ginkgo/v2 v2.20.1
8+
github.com/onsi/gomega v1.34.1
79
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20250707164913-ecb62273f7b5
810
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20250605082218-a58074898dd7
911
github.com/robfig/cron/v3 v3.0.1
1012
k8s.io/api v0.29.15
1113
k8s.io/apimachinery v0.29.15
14+
k8s.io/client-go v0.29.15
1215
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
1316
sigs.k8s.io/controller-runtime v0.17.6
1417
)
@@ -21,14 +24,17 @@ require (
2124
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
2225
github.com/fsnotify/fsnotify v1.7.0 // indirect
2326
github.com/go-logr/logr v1.4.3 // indirect
27+
github.com/go-logr/zapr v1.3.0 // indirect
2428
github.com/go-openapi/jsonpointer v0.21.0 // indirect
2529
github.com/go-openapi/jsonreference v0.21.0 // indirect
2630
github.com/go-openapi/swag v0.23.0 // indirect
31+
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
2732
github.com/gogo/protobuf v1.3.2 // indirect
2833
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
2934
github.com/golang/protobuf v1.5.4 // indirect
3035
github.com/google/gnostic-models v0.6.8 // indirect
3136
github.com/google/gofuzz v1.2.0 // indirect
37+
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
3238
github.com/google/uuid v1.6.0 // indirect
3339
github.com/imdario/mergo v0.3.16 // indirect
3440
github.com/josharian/intern v1.0.0 // indirect
@@ -43,21 +49,23 @@ require (
4349
github.com/prometheus/common v0.51.1 // indirect
4450
github.com/prometheus/procfs v0.13.0 // indirect
4551
github.com/spf13/pflag v1.0.5 // indirect
52+
go.uber.org/multierr v1.11.0 // indirect
53+
go.uber.org/zap v1.27.0 // indirect
4654
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
4755
golang.org/x/net v0.28.0 // indirect
4856
golang.org/x/oauth2 v0.18.0 // indirect
4957
golang.org/x/sys v0.23.0 // indirect
5058
golang.org/x/term v0.23.0 // indirect
5159
golang.org/x/text v0.17.0 // indirect
5260
golang.org/x/time v0.5.0 // indirect
61+
golang.org/x/tools v0.24.0 // indirect
5362
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
5463
google.golang.org/appengine v1.6.8 // indirect
5564
google.golang.org/protobuf v1.34.1 // indirect
5665
gopkg.in/inf.v0 v0.9.1 // indirect
5766
gopkg.in/yaml.v2 v2.4.0 // indirect
5867
gopkg.in/yaml.v3 v3.0.1 // indirect
5968
k8s.io/apiextensions-apiserver v0.29.15 // indirect
60-
k8s.io/client-go v0.29.15 // indirect
6169
k8s.io/component-base v0.29.15 // indirect
6270
k8s.io/klog/v2 v2.120.1 // indirect
6371
k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect

apis/go.sum

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF
2424
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
2525
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
2626
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
27-
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
2827
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
2928
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
3029
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1beta1 contains API Schema definitions for the placement v1beta1 API group
18+
// +kubebuilder:object:generate=true
19+
// +groupName=placement.openstack.org
20+
package v1beta1
21+
22+
import (
23+
"k8s.io/apimachinery/pkg/runtime/schema"
24+
"sigs.k8s.io/controller-runtime/pkg/scheme"
25+
)
26+
27+
var (
28+
// GroupVersion is group version used to register these objects
29+
GroupVersion = schema.GroupVersion{Group: "placement.openstack.org", Version: "v1beta1"}
30+
31+
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
32+
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
33+
34+
// AddToScheme adds the types in this group-version to the given scheme.
35+
AddToScheme = SchemeBuilder.AddToScheme
36+
)
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
Copyright 2022.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1beta1
18+
19+
import (
20+
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
21+
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
22+
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
23+
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
24+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
25+
"k8s.io/apimachinery/pkg/util/validation/field"
26+
corev1 "k8s.io/api/core/v1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
)
29+
30+
const (
31+
// DbSyncHash hash
32+
DbSyncHash = "dbsync"
33+
34+
// DeploymentHash hash used to detect changes
35+
DeploymentHash = "deployment"
36+
37+
// Container image fall-back defaults
38+
39+
// PlacementAPIContainerImage is the fall-back container image for PlacementAPI
40+
PlacementAPIContainerImage = "quay.io/podified-antelope-centos9/openstack-placement-api:current-podified"
41+
)
42+
43+
// PlacementAPISpec defines the desired state of PlacementAPI
44+
type PlacementAPISpec struct {
45+
PlacementAPISpecCore `json:",inline"`
46+
47+
// +kubebuilder:validation:Required
48+
// PlacementAPI Container Image URL (will be set to environmental default if empty)
49+
ContainerImage string `json:"containerImage"`
50+
}
51+
52+
// PlacementAPISpecCore -
53+
type PlacementAPISpecCore struct {
54+
// +kubebuilder:validation:Optional
55+
// +kubebuilder:default=60
56+
// +kubebuilder:validation:Minimum=10
57+
// APITimeout for HAProxy, Apache
58+
APITimeout int `json:"apiTimeout"`
59+
60+
// +kubebuilder:validation:Optional
61+
// +kubebuilder:default=placement
62+
// ServiceUser - optional username used for this service to register in keystone
63+
ServiceUser string `json:"serviceUser"`
64+
65+
// +kubebuilder:validation:Required
66+
// MariaDB instance name
67+
// Right now required by the maridb-operator to get the credentials from the instance to create the DB
68+
// Might not be required in future
69+
DatabaseInstance string `json:"databaseInstance"`
70+
71+
// +kubebuilder:validation:Optional
72+
// +kubebuilder:default=placement
73+
// DatabaseAccount - name of MariaDBAccount which will be used to connect.
74+
DatabaseAccount string `json:"databaseAccount"`
75+
76+
// +kubebuilder:validation:Optional
77+
// +kubebuilder:default=1
78+
// +kubebuilder:validation:Maximum=32
79+
// +kubebuilder:validation:Minimum=0
80+
// Replicas of placement API to run
81+
Replicas *int32 `json:"replicas"`
82+
83+
// +kubebuilder:validation:Required
84+
// Secret containing OpenStack password information for placement PlacementPassword
85+
Secret string `json:"secret"`
86+
87+
// +kubebuilder:validation:Optional
88+
// +kubebuilder:default={service: PlacementPassword}
89+
// PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret
90+
PasswordSelectors PasswordSelector `json:"passwordSelectors"`
91+
92+
// +kubebuilder:validation:Optional
93+
// NodeSelector to target subset of worker nodes running this service
94+
NodeSelector *map[string]string `json:"nodeSelector,omitempty"`
95+
96+
// +kubebuilder:validation:Optional
97+
// +kubebuilder:default=false
98+
// PreserveJobs - do not delete jobs after they finished e.g. to check logs
99+
PreserveJobs bool `json:"preserveJobs"`
100+
101+
// +kubebuilder:validation:Optional
102+
// CustomServiceConfig - customize the service config using this parameter to change service defaults,
103+
// or overwrite rendered information using raw OpenStack config format. The content gets added to
104+
// to /etc/<service>/<service>.conf.d directory as custom.conf file.
105+
CustomServiceConfig string `json:"customServiceConfig"`
106+
107+
// +kubebuilder:validation:Optional
108+
// DefaultConfigOverwrite - interface to overwrite default config files like policy.yaml.
109+
DefaultConfigOverwrite map[string]string `json:"defaultConfigOverwrite,omitempty"`
110+
111+
// +kubebuilder:validation:Optional
112+
// Resources - Compute Resources required by this service (Limits/Requests).
113+
// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
114+
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
115+
116+
// +kubebuilder:validation:Optional
117+
// NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network
118+
NetworkAttachments []string `json:"networkAttachments,omitempty"`
119+
120+
// +kubebuilder:validation:Optional
121+
// Override, provides the ability to override the generated manifest of several child resources.
122+
Override APIOverrideSpec `json:"override,omitempty"`
123+
124+
// +kubebuilder:validation:Optional
125+
// +operator-sdk:csv:customresourcedefinitions:type=spec
126+
// TLS - Parameters related to the TLS
127+
TLS tls.API `json:"tls,omitempty"`
128+
129+
// +kubebuilder:validation:Optional
130+
// TopologyRef to apply the Topology defined by the associated CR referenced
131+
// by name
132+
TopologyRef *topologyv1.TopoRef `json:"topologyRef,omitempty"`
133+
}
134+
135+
// APIOverrideSpec to override the generated manifest of several child resources.
136+
type APIOverrideSpec struct {
137+
// Override configuration for the Service created to serve traffic to the cluster.
138+
// The key must be the endpoint type (public, internal)
139+
Service map[service.Endpoint]service.RoutedOverrideSpec `json:"service,omitempty"`
140+
}
141+
142+
// PasswordSelector to identify the DB and AdminUser password from the Secret
143+
type PasswordSelector struct {
144+
// +kubebuilder:validation:Optional
145+
// +kubebuilder:default="PlacementPassword"
146+
// Service - Selector to get the service user password from the Secret
147+
Service string `json:"service"`
148+
}
149+
150+
// PlacementAPIStatus defines the observed state of PlacementAPI
151+
type PlacementAPIStatus struct {
152+
// ReadyCount of placement API instances
153+
ReadyCount int32 `json:"readyCount,omitempty"`
154+
155+
// Map of hashes to track e.g. job status
156+
Hash map[string]string `json:"hash,omitempty"`
157+
158+
// Conditions
159+
Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"`
160+
161+
// Placement Database Hostname
162+
DatabaseHostname string `json:"databaseHostname,omitempty"`
163+
164+
// NetworkAttachments status of the deployment pods
165+
NetworkAttachments map[string][]string `json:"networkAttachments,omitempty"`
166+
167+
//ObservedGeneration - the most recent generation observed for this service. If the observed generation is less than the spec generation, then the controller has not processed the latest changes.
168+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
169+
170+
// LastAppliedTopology - the last applied Topology
171+
LastAppliedTopology *topologyv1.TopoRef `json:"lastAppliedTopology,omitempty"`
172+
}
173+
174+
// PlacementAPI is the Schema for the placementapis API
175+
// +kubebuilder:object:root=true
176+
// +kubebuilder:subresource:status
177+
// +kubebuilder:printcolumn:name="NetworkAttachments",type="string",JSONPath=".spec.networkAttachments",description="NetworkAttachments"
178+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status"
179+
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message"
180+
type PlacementAPI struct {
181+
metav1.TypeMeta `json:",inline"`
182+
metav1.ObjectMeta `json:"metadata,omitempty"`
183+
184+
Spec PlacementAPISpec `json:"spec,omitempty"`
185+
Status PlacementAPIStatus `json:"status,omitempty"`
186+
}
187+
188+
// PlacementAPIList contains a list of PlacementAPI
189+
// +kubebuilder:object:root=true
190+
type PlacementAPIList struct {
191+
metav1.TypeMeta `json:",inline"`
192+
metav1.ListMeta `json:"metadata,omitempty"`
193+
Items []PlacementAPI `json:"items"`
194+
}
195+
196+
func init() {
197+
SchemeBuilder.Register(&PlacementAPI{}, &PlacementAPIList{})
198+
}
199+
200+
// IsReady - returns true if PlacementAPI is reconciled successfully
201+
func (instance PlacementAPI) IsReady() bool {
202+
return instance.Status.Conditions.IsTrue(condition.ReadyCondition)
203+
}
204+
205+
// RbacConditionsSet - set the conditions for the rbac object
206+
func (instance PlacementAPI) RbacConditionsSet(c *condition.Condition) {
207+
instance.Status.Conditions.Set(c)
208+
}
209+
210+
// RbacNamespace - return the namespace
211+
func (instance PlacementAPI) RbacNamespace() string {
212+
return instance.Namespace
213+
}
214+
215+
// RbacResourceName - return the name to be used for rbac objects (serviceaccount, role, rolebinding)
216+
func (instance PlacementAPI) RbacResourceName() string {
217+
return "placement-" + instance.Name
218+
}
219+
220+
// SetupDefaults - initializes any CRD field defaults based on environment variables (the defaulting mechanism itself is implemented via webhooks)
221+
func SetupDefaults() {
222+
// Acquire environmental defaults and initialize Placement defaults with them
223+
placementDefaults := PlacementAPIDefaults{
224+
ContainerImageURL: util.GetEnvVar("RELATED_IMAGE_PLACEMENT_API_IMAGE_URL_DEFAULT", PlacementAPIContainerImage),
225+
APITimeout: 60,
226+
}
227+
228+
SetupPlacementAPIDefaults(placementDefaults)
229+
}
230+
231+
// GetSecret returns the value of the Nova.Spec.Secret
232+
func (instance PlacementAPI) GetSecret() string {
233+
return instance.Spec.Secret
234+
}
235+
236+
// ValidateTopology -
237+
func (instance *PlacementAPISpecCore) ValidateTopology(
238+
basePath *field.Path,
239+
namespace string,
240+
) field.ErrorList {
241+
var allErrs field.ErrorList
242+
allErrs = append(allErrs, topologyv1.ValidateTopologyRef(
243+
instance.TopologyRef,
244+
*basePath.Child("topologyRef"), namespace)...)
245+
return allErrs
246+
}

0 commit comments

Comments
 (0)