-
Notifications
You must be signed in to change notification settings - Fork 296
Expand file tree
/
Copy pathopenstackcluster_types.go
More file actions
348 lines (293 loc) · 16.4 KB
/
openstackcluster_types.go
File metadata and controls
348 lines (293 loc) · 16.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
Copyright 2026 The Kubernetes Authors.
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 v1beta2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional"
)
const (
// ClusterFinalizer allows ReconcileOpenStackCluster to clean up OpenStack resources associated with OpenStackCluster before
// removing it from the apiserver.
ClusterFinalizer = "openstackcluster.infrastructure.cluster.x-k8s.io"
)
// OpenStackClusterSpec defines the desired state of OpenStackCluster.
// +kubebuilder:validation:XValidation:rule="has(self.disableExternalNetwork) && self.disableExternalNetwork ? !has(self.bastion) || !has(self.bastion.floatingIP) : true",message="bastion floating IP cannot be set when disableExternalNetwork is true"
// +kubebuilder:validation:XValidation:rule="has(self.disableExternalNetwork) && self.disableExternalNetwork ? has(self.disableAPIServerFloatingIP) && self.disableAPIServerFloatingIP : true",message="disableAPIServerFloatingIP cannot be false when disableExternalNetwork is true"
type OpenStackClusterSpec struct {
// ManagedSubnets describe OpenStack Subnets to be created. Cluster actuator will create a network,
// subnets with the defined CIDR, and a router connected to these subnets. Currently only one IPv4
// subnet is supported. If you leave this empty, no network will be created.
// +kubebuilder:validation:MaxItems=1
// +listType=atomic
// +optional
ManagedSubnets []SubnetSpec `json:"managedSubnets,omitempty"`
// Subnets specifies existing subnets to use if not ManagedSubnets are
// specified. All subnets must be in the network specified by Network.
// There can be zero, one, or two subnets. If no subnets are specified,
// all subnets in Network will be used. If 2 subnets are specified, one
// must be IPv4 and the other IPv6.
// +kubebuilder:validation:MaxItems=2
// +listType=atomic
// +optional
Subnets []SubnetParam `json:"subnets,omitempty"`
// Router specifies an existing router to be used if ManagedSubnets are
// specified. If specified, no new router will be created.
// +optional
Router *RouterParam `json:"router,omitempty"`
// ManagedNetwork specifies attributes of the network. The values are used only
// if the Cluster actuator creates the network.
// +kubebuilder:validation:XValidation:rule="self == null || has(self.mtu) || has(self.disablePortSecurity)",message="managedNetwork must not be empty if set"
// +optional
ManagedNetwork *ManagedNetwork `json:"managedNetwork,omitempty"`
// Network specifies an existing network to use if no ManagedSubnets
// are specified.
// +optional
Network *NetworkParam `json:"network,omitempty"`
// ExternalRouterIPs is an array of externalIPs on the respective subnets.
// This is necessary if the router needs a fixed ip in a specific subnet.
// +listType=atomic
// +optional
ExternalRouterIPs []ExternalRouterIPParam `json:"externalRouterIPs,omitempty"`
// ExternalNetwork is the OpenStack Network to be used to get public internet to the VMs.
// This option is ignored if DisableExternalNetwork is set to true.
//
// If ExternalNetwork is defined it must refer to exactly one external network.
//
// If ExternalNetwork is not defined or is empty the controller will use any
// existing external network as long as there is only one. It is an
// error if ExternalNetwork is not defined and there are multiple
// external networks unless DisableExternalNetwork is also set.
//
// If ExternalNetwork is not defined and there are no external networks
// the controller will proceed as though DisableExternalNetwork was set.
// +optional
ExternalNetwork *NetworkParam `json:"externalNetwork,omitempty"`
// DisableExternalNetwork specifies whether or not to attempt to connect the cluster
// to an external network. This allows for the creation of clusters when connecting
// to an external network is not possible or desirable, e.g. if using a provider network.
// +optional
DisableExternalNetwork optional.Bool `json:"disableExternalNetwork,omitempty"`
// APIServerLoadBalancer configures the optional LoadBalancer for the APIServer.
// If not specified, no load balancer will be created for the API server.
// +optional
APIServerLoadBalancer *APIServerLoadBalancer `json:"apiServerLoadBalancer,omitempty"`
// DisableAPIServerFloatingIP determines whether or not to attempt to attach a floating
// IP to the API server. This allows for the creation of clusters when attaching a floating
// IP to the API server (and hence, in many cases, exposing the API server to the internet)
// is not possible or desirable, e.g. if using a shared VLAN for communication between
// management and workload clusters or when the management cluster is inside the
// project network.
// This option requires that the API server use a VIP on the cluster network so that the
// underlying machines can change without changing ControlPlaneEndpoint.Host.
// When using a managed load balancer, this VIP will be managed automatically.
// If not using a managed load balancer, cluster configuration will fail without additional
// configuration to manage the VIP on the control plane machines, which falls outside of
// the scope of this controller.
// +optional
DisableAPIServerFloatingIP optional.Bool `json:"disableAPIServerFloatingIP,omitempty"`
// APIServerFloatingIP is the floatingIP which will be associated with the API server.
// The floatingIP will be created if it does not already exist.
// If not specified, a new floatingIP is allocated.
// This field is not used if DisableAPIServerFloatingIP is set to true.
// +optional
APIServerFloatingIP optional.String `json:"apiServerFloatingIP,omitempty"`
// APIServerFixedIP is the fixed IP which will be associated with the API server.
// In the case where the API server has a floating IP but not a managed load balancer,
// this field is not used.
// If a managed load balancer is used and this field is not specified, a fixed IP will
// be dynamically allocated for the load balancer.
// If a managed load balancer is not used AND the API server floating IP is disabled,
// this field MUST be specified and should correspond to a pre-allocated port that
// holds the fixed IP to be used as a VIP.
// +optional
APIServerFixedIP optional.String `json:"apiServerFixedIP,omitempty"`
// APIServerPort is the port on which the listener on the APIServer
// will be created. If specified, it must be an integer between 0 and 65535.
// +optional
APIServerPort optional.UInt16 `json:"apiServerPort,omitempty"`
// ManagedSecurityGroups determines whether OpenStack security groups for the cluster
// will be managed by the OpenStack provider or whether pre-existing security groups will
// be specified as part of the configuration.
// By default, the managed security groups have rules that allow the Kubelet, etcd, and the
// Kubernetes API server to function correctly.
// It's possible to add additional rules to the managed security groups.
// When defined to an empty struct, the managed security groups will be created with the default rules.
// +optional
ManagedSecurityGroups *ManagedSecurityGroups `json:"managedSecurityGroups,omitempty"`
// Tags to set on all resources in cluster which support tags
// +listType=set
// +optional
Tags []string `json:"tags,omitempty"`
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
// It is normally populated automatically by the OpenStackCluster
// controller during cluster provisioning. If it is set on creation the
// control plane endpoint will use the values set here in preference to
// values set elsewhere.
// ControlPlaneEndpoint cannot be modified after ControlPlaneEndpoint.Host has been set.
// +optional
ControlPlaneEndpoint *clusterv1.APIEndpoint `json:"controlPlaneEndpoint,omitempty"`
// ControlPlaneAvailabilityZones is the set of availability zones which
// control plane machines may be deployed to.
// +listType=set
// +optional
ControlPlaneAvailabilityZones []string `json:"controlPlaneAvailabilityZones,omitempty"`
// ControlPlaneOmitAvailabilityZone causes availability zone to be
// omitted when creating control plane nodes, allowing the Nova
// scheduler to make a decision on which availability zone to use based
// on other scheduling constraints
// +optional
ControlPlaneOmitAvailabilityZone optional.Bool `json:"controlPlaneOmitAvailabilityZone,omitempty"`
// Bastion is the OpenStack instance to login the nodes
//
// As a rolling update is not ideal during a bastion host session, we
// prevent changes to a running bastion configuration. To make changes, it's required
// to first set `enabled: false` which will remove the bastion and then changes can be made.
//+optional
Bastion *Bastion `json:"bastion,omitempty"`
// IdentityRef is a reference to a secret holding OpenStack credentials
// to be used when reconciling this cluster. It is also to reconcile
// machines unless overridden in the machine spec.
// +kubebuilder:validation:Required
IdentityRef OpenStackIdentityReference `json:"identityRef"`
}
// ClusterInitialization represents the initialization status of the cluster.
type ClusterInitialization struct {
// Provisioned is set to true when the initial provisioning of the cluster infrastructure is completed.
// The value of this field is never updated after provisioning is completed.
// +optional
Provisioned bool `json:"provisioned,omitempty"`
}
// OpenStackClusterStatus defines the observed state of OpenStackCluster.
type OpenStackClusterStatus struct {
// Initialization contains information about the initialization status of the cluster.
// +optional
Initialization *ClusterInitialization `json:"initialization,omitempty"`
// Network contains information about the created OpenStack Network.
// +optional
Network *NetworkStatusWithSubnets `json:"network,omitempty"`
// ExternalNetwork contains information about the external network used for default ingress and egress traffic.
// +optional
ExternalNetwork *NetworkStatus `json:"externalNetwork,omitempty"`
// Router describes the default cluster router
// +optional
Router *Router `json:"router,omitempty"`
// APIServerLoadBalancer describes the api server load balancer if one exists
// +optional
APIServerLoadBalancer *LoadBalancer `json:"apiServerLoadBalancer,omitempty"`
// FailureDomains represent OpenStack availability zones
FailureDomains []clusterv1.FailureDomain `json:"failureDomains,omitempty"`
// ControlPlaneSecurityGroup contains the information about the
// OpenStack Security Group that needs to be applied to control plane
// nodes.
// +optional
ControlPlaneSecurityGroup *SecurityGroupStatus `json:"controlPlaneSecurityGroup,omitempty"`
// WorkerSecurityGroup contains the information about the OpenStack
// Security Group that needs to be applied to worker nodes.
// +optional
WorkerSecurityGroup *SecurityGroupStatus `json:"workerSecurityGroup,omitempty"`
// BastionSecurityGroup contains the information about the OpenStack
// Security Group that needs to be applied to worker nodes.
// +optional
BastionSecurityGroup *SecurityGroupStatus `json:"bastionSecurityGroup,omitempty"`
// Bastion contains the information about the deployed bastion host
// +optional
Bastion *BastionStatus `json:"bastion,omitempty"`
// Conditions defines current service state of the OpenStackCluster.
// This field surfaces into Cluster's status.conditions[InfrastructureReady] condition.
// The Ready condition must surface issues during the entire lifecycle of the OpenStackCluster
// (both during initial provisioning and after the initial provisioning is completed).
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:path=openstackclusters,scope=Namespaced,categories=cluster-api,shortName=osc
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this OpenStackCluster belongs"
// +kubebuilder:printcolumn:name="Network",type="string",JSONPath=".status.network.id",description="Network the cluster is using"
// +kubebuilder:printcolumn:name="Endpoint",type="string",JSONPath=".spec.controlPlaneEndpoint.host",description="API Endpoint",priority=1
// +kubebuilder:printcolumn:name="Bastion IP",type="string",JSONPath=".status.bastion.floatingIP",description="Bastion address for breakglass access"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of OpenStackCluster"
// OpenStackCluster is the Schema for the openstackclusters API.
type OpenStackCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec OpenStackClusterSpec `json:"spec,omitempty"`
Status OpenStackClusterStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// OpenStackClusterList contains a list of OpenStackCluster.
type OpenStackClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []OpenStackCluster `json:"items"`
}
// ManagedNetwork specifies attributes of the network.
type ManagedNetwork struct {
// MTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID.
// This value will be used only if the Cluster actuator creates the network.
// If left empty, the network will have the default MTU defined in Openstack network service.
// To use this field, the Openstack installation requires the net-mtu neutron API extension.
// +optional
MTU optional.Int `json:"mtu,omitempty"`
// DisablePortSecurity disables the port security of the network created for the
// Kubernetes cluster, which also disables SecurityGroups
// +optional
DisablePortSecurity optional.Bool `json:"disablePortSecurity,omitempty"`
}
// ManagedSecurityGroups defines the desired state of security groups and rules for the cluster.
type ManagedSecurityGroups struct {
// allNodesSecurityGroupRules defines the rules that should be applied to all nodes.
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +optional
AllNodesSecurityGroupRules []SecurityGroupRuleSpec `json:"allNodesSecurityGroupRules,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
// controlPlaneNodesSecurityGroupRules defines the rules that should be applied to control plane nodes.
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +optional
ControlPlaneNodesSecurityGroupRules []SecurityGroupRuleSpec `json:"controlPlaneNodesSecurityGroupRules,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
// workerNodesSecurityGroupRules defines the rules that should be applied to worker nodes.
// +patchMergeKey=name
// +patchStrategy=merge
// +listType=map
// +listMapKey=name
// +optional
WorkerNodesSecurityGroupRules []SecurityGroupRuleSpec `json:"workerNodesSecurityGroupRules,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
// AllowAllInClusterTraffic allows all ingress and egress traffic between cluster nodes when set to true.
// +kubebuilder:default=false
// +kubebuilder:validation:Required
AllowAllInClusterTraffic bool `json:"allowAllInClusterTraffic"`
}
var _ IdentityRefProvider = &OpenStackCluster{}
// GetConditions returns the observations of the operational state of the OpenStackCluster resource.
func (c *OpenStackCluster) GetConditions() []metav1.Condition {
return c.Status.Conditions
}
// SetConditions sets the underlying service state of the OpenStackCluster to the predescribed clusterv1.Conditions.
func (c *OpenStackCluster) SetConditions(conditions []metav1.Condition) {
c.Status.Conditions = conditions
}
// GetIdentifyRef returns the cluster's namespace and IdentityRef.
func (c *OpenStackCluster) GetIdentityRef() (*string, *OpenStackIdentityReference) {
return &c.Namespace, &c.Spec.IdentityRef
}
func init() {
objectTypes = append(objectTypes, &OpenStackCluster{}, &OpenStackClusterList{})
}