Skip to content

Commit da8f696

Browse files
committed
Implement ScalewayCluster and add ScalewayClusterTemplate
1 parent 7892b70 commit da8f696

Some content is hidden

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

41 files changed

+4313
-66
lines changed

.golangci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ linters:
2929
- goimports
3030
- gosimple
3131
- govet
32+
- importas
3233
- ineffassign
3334
- lll
3435
- misspell
@@ -45,3 +46,15 @@ linters-settings:
4546
revive:
4647
rules:
4748
- name: comment-spacings
49+
importas:
50+
alias:
51+
- pkg: sigs.k8s.io/controller-runtime/pkg/log
52+
alias: logf
53+
- pkg: sigs.k8s.io/cluster-api/api/v1beta1
54+
alias: clusterv1
55+
- pkg: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1
56+
alias: infrav1
57+
- pkg: k8s.io/apimachinery/pkg/api/errors
58+
alias: apierrors
59+
- pkg: k8s.io/apimachinery/pkg/util/errors
60+
alias: utilerrors

PROJECT

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,12 @@ resources:
2626
kind: ScalewayMachine
2727
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1
2828
version: v1alpha1
29+
- api:
30+
crdVersion: v1
31+
namespaced: true
32+
domain: cluster.x-k8s.io
33+
group: infrastructure
34+
kind: ScalewayClusterTemplate
35+
path: github.com/scaleway/cluster-api-provider-scaleway/api/v1alpha1
36+
version: v1alpha1
2937
version: "3"

api/v1alpha1/scalewaycluster_types.go

Lines changed: 208 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,228 @@ package v1alpha1
22

33
import (
44
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
56
)
67

7-
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
8-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
8+
const ClusterFinalizer = "scalewaycluster.infrastructure.cluster.x-k8s.io/sc-protection"
99

1010
// ScalewayClusterSpec defines the desired state of ScalewayCluster.
11+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.controlPlaneEndpoint) || has(self.controlPlaneEndpoint)", message="controlPlaneEndpoint is required once set"
1112
type ScalewayClusterSpec struct {
12-
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
13-
// Important: Run "make" to regenerate code after modifying this file
13+
// Region represents the region where the cluster will be hosted.
14+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
15+
// +kubebuilder:validation:MinLength=1
16+
// +kubebuilder:validation:MaxLength=10
17+
Region string `json:"region"`
1418

15-
// Foo is an example field of ScalewayCluster. Edit scalewaycluster_types.go to remove/update
16-
Foo string `json:"foo,omitempty"`
19+
// Network contains network related options for the cluster.
20+
// +optional
21+
Network *NetworkSpec `json:"network,omitempty"`
22+
23+
// ScalewaySecretName is the name of the secret that contains the Scaleway client parameters.
24+
// The following keys are required: SCW_ACCESS_KEY, SCW_SECRET_KEY, SCW_DEFAULT_PROJECT_ID.
25+
// The following key is optional: SCW_API_URL.
26+
ScalewaySecretName string `json:"scalewaySecretName"`
27+
28+
// FailureDomains is a list of failure domains where the control-plane nodes will be created.
29+
// Failure domains correspond to Scaleway zones inside the cluster region (e.g. fr-par-1).
30+
// +listType=set
31+
// +optional
32+
FailureDomains []string `json:"failureDomains,omitempty"`
33+
34+
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
35+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
36+
// +optional
37+
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint,omitempty"`
38+
}
39+
40+
// NetworkSpec defines network specific settings.
41+
// +kubebuilder:validation:XValidation:rule="!has(self.controlPlaneExtraLoadBalancers) || has(self.controlPlaneDNS)",message="controlPlaneDNS is required when controlPlaneExtraLoadBalancers is set"
42+
// +kubebuilder:validation:XValidation:rule="has(self.controlPlaneDNS) == has(oldSelf.controlPlaneDNS)",message="controlPlaneDNS cannot be added or removed"
43+
// +kubebuilder:validation:XValidation:rule="has(self.privateNetwork) == has(oldSelf.privateNetwork)",message="privateNetwork cannot be added or removed"
44+
// +kubebuilder:validation:XValidation:rule="!has(self.publicGateways) || has(self.privateNetwork) && self.privateNetwork.enabled",message="privateNetwork is required when publicGateways is set"
45+
type NetworkSpec struct {
46+
// ControlPlaneLoadBalancer contains loadbalancer settings.
47+
// +optional
48+
ControlPlaneLoadBalancer *ControlPlaneLoadBalancerSpec `json:"controlPlaneLoadBalancer,omitempty"`
49+
50+
// ControlPlaneExtraLoadBalancers allows configuring additional LoadBalancers.
51+
// Because Scaleway LoadBalancers are currently zonal resources, you may set
52+
// up to 3 additional LoadBalancers for achieving regional redundancy. It is
53+
// mandatory to set the controlPlaneDNS field when you do so.
54+
// This may be removed in the future, when Scaleway supports regional LoadBalancers.
55+
// +kubebuilder:validation:MaxItems=3
56+
// +optional
57+
ControlPlaneExtraLoadBalancers []LoadBalancerSpec `json:"controlPlaneExtraLoadBalancers,omitempty"`
58+
59+
// ControlPlaneDNS allows configuring a Scaleway Domain DNS Zone.
60+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
61+
// +optional
62+
ControlPlaneDNS *ControlPlaneDNSSpec `json:"controlPlaneDNS,omitempty"`
63+
64+
// PrivateNetwork allows attaching machines of the cluster to a Private Network.
65+
// +optional
66+
PrivateNetwork *PrivateNetworkSpec `json:"privateNetwork,omitempty"`
67+
68+
// PublicGateways allows to create Public Gateways that will be attached to the
69+
// Private Network of the cluster.
70+
// +kubebuilder:validation:MaxItems=6
71+
// +optional
72+
PublicGateways []PublicGatewaySpec `json:"publicGateways,omitempty"`
73+
}
74+
75+
// LoadBalancerSpec defines loadbalancer parameters.
76+
type LoadBalancerSpec struct {
77+
// Zone where to create the loadbalancer. Must be in the same region as the
78+
// cluster. Defaults to the first zone of the region.
79+
// +optional
80+
Zone *string `json:"zone,omitempty"`
81+
82+
// Load Balancer commercial offer type.
83+
// +kubebuilder:default="LB-S"
84+
// +optional
85+
Type *string `json:"type,omitempty"`
86+
87+
// IP to use when creating a loadbalancer.
88+
// +kubebuilder:validation:Format=ipv4
89+
// +optional
90+
IP *string `json:"ip,omitempty"`
91+
}
92+
93+
// ControlPlaneLoadBalancerSpec defines control-plane loadbalancer settings for the cluster.
94+
// +kubebuilder:validation:XValidation:rule="has(self.port) == has(oldSelf.port)",message="port cannot be added or removed"
95+
type ControlPlaneLoadBalancerSpec struct {
96+
// +kubebuilder:validation:XValidation:rule="has(self.ip) == has(oldSelf.ip)",message="ip cannot be added or removed"
97+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ip) || self.ip == oldSelf.ip",message="ip is immutable"
98+
// +kubebuilder:validation:XValidation:rule="has(self.zone) == has(oldSelf.zone)",message="zone cannot be added or removed"
99+
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.zone) || self.zone == oldSelf.zone",message="zone is immutable"
100+
LoadBalancerSpec `json:",inline"`
101+
102+
// Port configured on the Load Balancer. It must be valid port range (1-65535).
103+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
104+
// +kubebuilder:validation:Minimum=1
105+
// +kubebuilder:validation:Maximum=65535
106+
Port *int32 `json:"port,omitempty"`
107+
108+
// AllowedRanges allows to set a list of allowed IP ranges that can access
109+
// the cluster through the loadbalancer. When unset, all IP ranges are allowed.
110+
// To allow the cluster to work properly, public IPs of nodes and Public
111+
// Gateways will automatically be allowed. However, if this field is set,
112+
// you MUST manually allow IPs of the nodes of your management cluster.
113+
// +kubebuilder:validation:MaxItems=30
114+
// +listType=set
115+
// +optional
116+
AllowedRanges []CIDR `json:"allowedRanges,omitempty"`
117+
}
118+
119+
// CIDR is an IP address range in CIDR notation (for example, "10.0.0.0/8" or "fd00::/8").
120+
// +kubebuilder:validation:XValidation:rule="isCIDR(self)",message="value must be a valid CIDR network address"
121+
// +kubebuilder:validation:MaxLength:=43
122+
// +kubebuilder:validation:MinLength:=1
123+
type CIDR string
124+
125+
type ControlPlaneDNSSpec struct {
126+
// Domain is the DNS Zone that this record should live in. It must be pre-existing in your Scaleway account.
127+
// The format must be a string that conforms to the definition of a subdomain in DNS (RFC 1123).
128+
// +kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
129+
Domain string `json:"domain"`
130+
// Name is the DNS short name of the record (non-FQDN). The format must consist of
131+
// alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character.
132+
// +kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9.]*[a-z0-9])?$
133+
Name string `json:"name"`
134+
}
135+
136+
// PrivateNetworkSpec defines Private Network settings for the cluster.
137+
// +kubebuilder:validation:XValidation:rule="has(self.vpcID) == has(oldSelf.vpcID)",message="vpcID cannot be added or removed"
138+
// +kubebuilder:validation:XValidation:rule="has(self.id) == has(oldSelf.id)",message="id cannot be added or removed"
139+
// +kubebuilder:validation:XValidation:rule="has(self.subnet) == has(oldSelf.subnet)",message="subnet cannot be added or removed"
140+
// +kubebuilder:validation:XValidation:rule="has(self.id) && !has(self.subnet) || !has(self.id)",message="subnet cannot be set when id is set"
141+
// +kubebuilder:validation:XValidation:rule="has(self.id) && !has(self.vpcID) || !has(self.id)",message="vpcID cannot be set when id is set"
142+
type PrivateNetworkSpec struct {
143+
// Set to true to automatically attach machines to a Private Network.
144+
// The Private Network is automatically created if no existing Private
145+
// Network ID is provided.
146+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
147+
Enabled bool `json:"enabled"`
148+
149+
// Set a Private Network ID to reuse an existing Private Network.
150+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
151+
// +optional
152+
ID *string `json:"id,omitempty"`
153+
154+
// Set the VPC ID where the new Private Network will be created.
155+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
156+
// +optional
157+
VPCID *string `json:"vpcID,omitempty"`
158+
159+
// Optional subnet for the Private Network. Only used on newly created Private Networks.
160+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
161+
// +optional
162+
Subnet *string `json:"subnet,omitempty"`
163+
}
164+
165+
// PublicGatewaySpec defines Public Gateway settings for the cluster.
166+
type PublicGatewaySpec struct {
167+
// Public Gateway commercial offer type.
168+
// +kubebuilder:default="VPC-GW-S"
169+
// +optional
170+
Type *string `json:"type,omitempty"`
171+
172+
// IP to use when creating a Public Gateway.
173+
// +kubebuilder:validation:Format=ipv4
174+
// +optional
175+
IP *string `json:"ip,omitempty"`
176+
177+
// Zone where to create the Public Gateway. Must be in the same region as the
178+
// cluster. Defaults to the first zone of the region.
179+
// +optional
180+
Zone *string `json:"zone,omitempty"`
17181
}
18182

19183
// ScalewayClusterStatus defines the observed state of ScalewayCluster.
20184
type ScalewayClusterStatus struct {
21-
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
22-
// Important: Run "make" to regenerate code after modifying this file
185+
// Ready denotes that the Scaleway cluster infrastructure is fully provisioned.
186+
// NOTE: this field is part of the Cluster API contract and it is used to orchestrate provisioning.
187+
// The value of this field is never updated after provisioning is completed.
188+
// +optional
189+
Ready bool `json:"ready"`
190+
191+
// Network contains information about network resources of the cluster.
192+
// +optional
193+
Network *NetworkStatus `json:"network,omitempty"`
194+
195+
// FailureDomains is a list of failure domain objects synced from the infrastructure provider.
196+
// +optional
197+
FailureDomains clusterv1.FailureDomains `json:"failureDomains,omitempty"`
198+
}
199+
200+
// NetworkStatus contains information about network resources of the cluster.
201+
type NetworkStatus struct {
202+
// PrivateNetworkID is set if the cluster has an associated Private Network.
203+
// +optional
204+
PrivateNetworkID *string `json:"privateNetworkID,omitempty"`
205+
206+
// PublicGatewayIDs is a list of Public Gateway IDs.
207+
// +optional
208+
PublicGatewayIDs []string `json:"publicGatewayIDs,omitempty"`
209+
210+
// LoadBalancerIP is the public IP of the cluster control-plane.
211+
// +optional
212+
LoadBalancerIP *string `json:"loadBalancerIP,omitempty"`
213+
214+
// ExtraLoadBalancerIPs is a list of IPs of the extra loadbalancers.
215+
// +optional
216+
ExtraLoadBalancerIPs []string `json:"extraLoadBalancerIPs,omitempty"`
23217
}
24218

25219
// +kubebuilder:object:root=true
26220
// +kubebuilder:subresource:status
221+
// +kubebuilder:printcolumn:name="Host",type="string",JSONPath=".spec.controlPlaneEndpoint.host",description="Host of the control plane"
222+
// +kubebuilder:printcolumn:name="Port",type="integer",JSONPath=".spec.controlPlaneEndpoint.port",description="Port of the control plane"
223+
// +kubebuilder:printcolumn:name="Region",type="string",JSONPath=".spec.region",description="Region of the cluster"
224+
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready",description="Ready is true when the cluster is fully provisioned"
225+
// +kubebuilder:resource:path=scalewayclusters,scope=Namespaced,categories=cluster-api,shortName=sc
226+
// +kubebuilder:storageversion
27227

28228
// ScalewayCluster is the Schema for the scalewayclusters API.
29229
type ScalewayCluster struct {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package v1alpha1
2+
3+
import (
4+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5+
)
6+
7+
// ScalewayClusterTemplateSpec defines the desired state of ScalewayClusterTemplate.
8+
type ScalewayClusterTemplateSpec struct {
9+
Template ScalewayClusterTemplateResource `json:"template"`
10+
}
11+
12+
type ScalewayClusterTemplateResource struct {
13+
// Standard object's metadata.
14+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
15+
// +optional
16+
ObjectMeta metav1.ObjectMeta `json:"metadata,omitempty"`
17+
Spec ScalewayClusterSpec `json:"spec"`
18+
}
19+
20+
// +kubebuilder:object:root=true
21+
// +kubebuilder:resource:path=scalewayclustertemplates,scope=Namespaced,categories=cluster-api,shortName=sct
22+
// +kubebuilder:storageversion
23+
24+
// ScalewayClusterTemplate is the Schema for the scalewayclustertemplates API.
25+
type ScalewayClusterTemplate struct {
26+
metav1.TypeMeta `json:",inline"`
27+
metav1.ObjectMeta `json:"metadata,omitempty"`
28+
29+
Spec ScalewayClusterTemplateSpec `json:"spec,omitempty"`
30+
}
31+
32+
// +kubebuilder:object:root=true
33+
34+
// ScalewayClusterTemplateList contains a list of ScalewayClusterTemplate.
35+
type ScalewayClusterTemplateList struct {
36+
metav1.TypeMeta `json:",inline"`
37+
metav1.ListMeta `json:"metadata,omitempty"`
38+
Items []ScalewayClusterTemplate `json:"items"`
39+
}
40+
41+
func init() {
42+
SchemeBuilder.Register(&ScalewayClusterTemplate{}, &ScalewayClusterTemplateList{})
43+
}

api/v1alpha1/scalewaymachine_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type ScalewayMachineStatus struct {
2424

2525
// +kubebuilder:object:root=true
2626
// +kubebuilder:subresource:status
27+
// +kubebuilder:resource:path=scalewaymachines,scope=Namespaced,categories=cluster-api,shortName=sm
28+
// +kubebuilder:storageversion
2729

2830
// ScalewayMachine is the Schema for the scalewaymachines API.
2931
type ScalewayMachine struct {

0 commit comments

Comments
 (0)