Skip to content

Commit c8470e7

Browse files
committed
add v1beta1 CRDs for LM and LC
1 parent 1c8cb44 commit c8470e7

15 files changed

+4131
-4
lines changed

PROJECT

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,20 @@ resources:
129129
kind: FirewallRule
130130
path: github.com/linode/cluster-api-provider-linode/api/v1alpha2
131131
version: v1alpha2
132+
- api:
133+
crdVersion: v1
134+
namespaced: true
135+
domain: cluster.x-k8s.io
136+
group: infrastructure
137+
kind: LinodeCluster
138+
path: github.com/linode/cluster-api-provider-linode/api/v1beta1
139+
version: v1beta1
140+
- api:
141+
crdVersion: v1
142+
namespaced: true
143+
domain: cluster.x-k8s.io
144+
group: infrastructure
145+
kind: LinodeMachine
146+
path: github.com/linode/cluster-api-provider-linode/api/v1beta1
147+
version: v1beta1
132148
version: "3"

api/v1alpha2/linodemachine_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type LinodeMachineSpec struct {
5656
Type string `json:"type,omitempty"`
5757

5858
// group is the Linode group to create the instance in.
59+
// Deprecated: group is a deprecated property denoting a group label for the Linode.
5960
// +optional
6061
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
6162
Group string `json:"group,omitempty"`

api/v1beta1/groupversion_info.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2023 Akamai Technologies, Inc.
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 infrastructure v1beta1 API group
18+
// +kubebuilder:object:generate=true
19+
// +groupName=infrastructure.cluster.x-k8s.io
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: "infrastructure.cluster.x-k8s.io", 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+
)

api/v1beta1/linodecluster_types.go

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
/*
2+
Copyright 2023 Akamai Technologies, Inc.
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+
corev1 "k8s.io/api/core/v1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
23+
)
24+
25+
const (
26+
// ClusterFinalizer allows ReconcileLinodeCluster to clean up Linode resources associated
27+
// with LinodeCluster before removing it from the apiserver.
28+
ClusterFinalizer = "linodecluster.infrastructure.cluster.x-k8s.io"
29+
ConditionPaused = "Paused"
30+
)
31+
32+
// LinodeClusterSpec defines the desired state of LinodeCluster
33+
type LinodeClusterSpec struct {
34+
// region the LinodeCluster lives in.
35+
// +kubebuilder:validation:MinLength=1
36+
// +required
37+
Region string `json:"region,omitempty"`
38+
39+
// controlPlaneEndpoint represents the endpoint used to communicate with the LinodeCluster control plane
40+
// If ControlPlaneEndpoint is unset then the Nodebalancer ip will be used.
41+
// +optional
42+
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`
43+
44+
// network encapsulates all things related to Linode network.
45+
// +optional
46+
Network NetworkSpec `json:"network"`
47+
48+
// vpcRef is a reference to a VPC object. This makes the Linodes use the specified VPC.
49+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
50+
// +optional
51+
VPCRef *corev1.ObjectReference `json:"vpcRef,omitempty"`
52+
53+
// vpcID is the ID of an existing VPC in Linode.
54+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
55+
// +optional
56+
VPCID *int `json:"vpcID,omitempty"`
57+
58+
// nodeBalancerFirewallRef is a reference to a NodeBalancer Firewall object. This makes the linode use the specified NodeBalancer Firewall.
59+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
60+
// +optional
61+
NodeBalancerFirewallRef *corev1.ObjectReference `json:"nodeBalancerFirewallRef,omitempty"`
62+
63+
// objectStore defines a supporting Object Storage bucket for cluster operations. This is currently used for
64+
// bootstrapping (e.g. Cloud-init).
65+
// +optional
66+
ObjectStore *ObjectStore `json:"objectStore,omitempty"`
67+
68+
// credentialsRef is a reference to a Secret that contains the credentials to use for provisioning this cluster. If not
69+
// supplied, then the credentials of the controller will be used.
70+
// +optional
71+
CredentialsRef *corev1.SecretReference `json:"credentialsRef,omitempty"`
72+
}
73+
74+
// LinodeClusterStatus defines the observed state of LinodeCluster
75+
type LinodeClusterStatus struct {
76+
// conditions define the current service state of the LinodeCluster.
77+
// +optional
78+
// +listType=map
79+
// +listMapKey=type
80+
// +patchStrategy=merge
81+
// +patchMergeKey=type
82+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
83+
84+
// ready denotes that the cluster (infrastructure) is ready.
85+
// +optional
86+
Ready bool `json:"ready"`
87+
88+
// failureReason will be set in the event that there is a terminal problem
89+
// reconciling the LinodeCluster and will contain a succinct value suitable
90+
// for machine interpretation.
91+
// +optional
92+
FailureReason *string `json:"failureReason,omitempty"`
93+
94+
// failureMessage will be set in the event that there is a terminal problem
95+
// reconciling the LinodeCluster and will contain a more verbose string suitable
96+
// for logging and human consumption.
97+
// +optional
98+
FailureMessage *string `json:"failureMessage,omitempty"`
99+
}
100+
101+
// +kubebuilder:object:root=true
102+
// +kubebuilder:resource:path=linodeclusters,scope=Namespaced,categories=cluster-api,shortName=lc
103+
// +kubebuilder:subresource:status
104+
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this LinodeCluster belongs"
105+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Cluster infrastructure is ready for Linode instances"
106+
// +kubebuilder:printcolumn:name="Endpoint",type="string",JSONPath=".spec.ControlPlaneEndpoint",description="API Endpoint",priority=1
107+
// +kubebuilder:storageversion
108+
109+
// LinodeCluster is the Schema for the linodeclusters API
110+
type LinodeCluster struct {
111+
metav1.TypeMeta `json:",inline"`
112+
113+
// metadata is the standard object's metadata.
114+
// +optional
115+
metav1.ObjectMeta `json:"metadata,omitempty"`
116+
117+
// spec is the desired state of the LinodeCluster.
118+
// +required
119+
Spec LinodeClusterSpec `json:"spec,omitzero,omitempty"`
120+
121+
// status is the observed state of the LinodeCluster.
122+
// +optional
123+
Status LinodeClusterStatus `json:"status,omitempty"`
124+
}
125+
126+
func (lc *LinodeCluster) SetCondition(cond metav1.Condition) {
127+
if cond.LastTransitionTime.IsZero() {
128+
cond.LastTransitionTime = metav1.Now()
129+
}
130+
for i := range lc.Status.Conditions {
131+
if lc.Status.Conditions[i].Type == cond.Type {
132+
lc.Status.Conditions[i] = cond
133+
return
134+
}
135+
}
136+
lc.Status.Conditions = append(lc.Status.Conditions, cond)
137+
}
138+
139+
func (lc *LinodeCluster) GetCondition(condType string) *metav1.Condition {
140+
for i := range lc.Status.Conditions {
141+
if lc.Status.Conditions[i].Type == condType {
142+
return &lc.Status.Conditions[i]
143+
}
144+
}
145+
146+
return nil
147+
}
148+
149+
func (lc *LinodeCluster) IsPaused() bool {
150+
for i := range lc.Status.Conditions {
151+
if lc.Status.Conditions[i].Type == ConditionPaused {
152+
return lc.Status.Conditions[i].Status == metav1.ConditionTrue
153+
}
154+
}
155+
return false
156+
}
157+
158+
// NetworkSpec encapsulates Linode networking resources.
159+
type NetworkSpec struct {
160+
// loadBalancerType is the type of load balancer to use, defaults to NodeBalancer if not otherwise set.
161+
// +kubebuilder:validation:Enum=NodeBalancer;dns;external
162+
// +kubebuilder:default=NodeBalancer
163+
// +optional
164+
LoadBalancerType string `json:"loadBalancerType,omitempty"`
165+
166+
// DNSConfig contains configuration for DNS-based load balancing. Ignored if LoadBalancerType is not set to "dns".
167+
// +optional
168+
DNSConfig *DNSConfig `json:"dnsConfig,omitempty"`
169+
170+
// NodeBalancerConfig contains configuration for NodeBalancer-based load balancing. Ignored if LoadBalancerType is not set to "NodeBalancer".
171+
// +optional
172+
NodeBalancerConfig *NodeBalancerConfig `json:"nodeBalancerConfig,omitempty"`
173+
174+
// apiserverLoadBalancerPort used by the api server. It must be valid ports range (1-65535).
175+
// If omitted, default value is 6443.
176+
// +kubebuilder:validation:Minimum=1
177+
// +kubebuilder:validation:Maximum=65535
178+
// +optional
179+
ApiserverLoadBalancerPort int `json:"apiserverLoadBalancerPort,omitempty"`
180+
181+
// subnetName is the name/label of the VPC subnet to be used by the cluster
182+
// +optional
183+
SubnetName string `json:"subnetName,omitempty"`
184+
185+
// useVlan provisions a cluster that uses VLANs instead of VPCs. IPAM is managed internally.
186+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
187+
// +optional
188+
UseVlan bool `json:"useVlan,omitempty"`
189+
}
190+
191+
type DNSConfig struct {
192+
// Provider is the provider who manages the domain.
193+
// +kubebuilder:validation:Enum=linode;akamai
194+
// +kubebuilder:default=linode
195+
// +optional
196+
Provider string `json:"dnsProvider,omitempty"`
197+
198+
// dnsRootDomain is the root domain used to create a DNS entry for the control-plane endpoint.
199+
// +optional
200+
DNSRootDomain string `json:"dnsRootDomain,omitempty"`
201+
202+
// dnsUniqueIdentifier is the unique identifier for the DNS. This let clusters with the same name have unique
203+
// DNS record
204+
// If not set, CAPL will create a unique identifier for you
205+
// +optional
206+
DNSUniqueIdentifier string `json:"dnsUniqueIdentifier,omitempty"`
207+
208+
// dnsTTLsec is the TTL for the domain record
209+
// +kubebuilder:default=30
210+
// +optional
211+
DNSTTLSec int `json:"dnsTTLsec,omitempty"`
212+
213+
// dnsSubDomainOverride is used to override CAPL's construction of the controlplane endpoint
214+
// If set, this will override the DNS subdomain from <clustername>-<uniqueid>.<rootdomain> to <overridevalue>.<rootdomain>
215+
// +optional
216+
DNSSubDomainOverride string `json:"dnsSubDomainOverride,omitempty"`
217+
}
218+
219+
type NodeBalancerConfig struct {
220+
// nodeBalancerID is the id of NodeBalancer.
221+
// +optional
222+
NodeBalancerID *int `json:"nodeBalancerID,omitempty"`
223+
224+
// nodeBalancerFirewallID is the id of NodeBalancer Firewall.
225+
// +optional
226+
NodeBalancerFirewallID *int `json:"nodeBalancerFirewallID,omitempty"`
227+
228+
// apiserverNodeBalancerConfigID is the config ID of api server NodeBalancer config.
229+
// +optional
230+
ApiserverNodeBalancerConfigID *int `json:"apiserverNodeBalancerConfigID,omitempty"`
231+
232+
// nodeBalancerBackendIPv4Range is the subnet range we want to provide for creating nodebalancer in VPC.
233+
// example: 10.10.10.0/30
234+
// +optional
235+
NodeBalancerBackendIPv4Range string `json:"nodeBalancerBackendIPv4Range,omitempty"`
236+
237+
// additionalPorts contains list of ports to be configured with NodeBalancer.
238+
// +optional
239+
// +listType=map
240+
// +listMapKey=port
241+
AdditionalPorts []LinodeNBPortConfig `json:"additionalPorts,omitempty"`
242+
243+
// enableVPCBackends toggles VPC-scoped NodeBalancer and VPC backend IP usage.
244+
// If set to false (default), the NodeBalancer will not be created in a VPC and
245+
// backends will use Linode private IPs. If true, the NodeBalancer will be
246+
// created in the configured VPC (when VPCRef or VPCID is set) and backends
247+
// will use VPC IPs.
248+
// +kubebuilder:default=false
249+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
250+
// +optional
251+
EnableVPCBackends bool `json:"enableVPCBackends,omitempty"`
252+
}
253+
254+
type LinodeNBPortConfig struct {
255+
// port configured on the NodeBalancer. It must be valid port range (1-65535).
256+
// +kubebuilder:validation:Minimum=1
257+
// +kubebuilder:validation:Maximum=65535
258+
// +required
259+
Port int `json:"port,omitempty"`
260+
261+
// nodeBalancerConfigID is the config ID of port's NodeBalancer config.
262+
// +optional
263+
NodeBalancerConfigID *int `json:"nodeBalancerConfigID,omitempty"`
264+
}
265+
266+
// ObjectStore defines a supporting Object Storage bucket for cluster operations. This is currently used for
267+
// bootstrapping (e.g. Cloud-init).
268+
type ObjectStore struct {
269+
// presignedURLDuration defines the duration for which presigned URLs are valid.
270+
//
271+
// This is used to generate presigned URLs for S3 Bucket objects, which are used by
272+
// control-plane and worker nodes to fetch bootstrap data.
273+
// +optional
274+
PresignedURLDuration *metav1.Duration `json:"presignedURLDuration,omitempty"`
275+
276+
// credentialsRef is a reference to a Secret that contains the credentials to use for accessing the Cluster Object Store.
277+
// +optional
278+
CredentialsRef corev1.SecretReference `json:"credentialsRef,omitempty"`
279+
}
280+
281+
// +kubebuilder:object:root=true
282+
283+
// LinodeClusterList contains a list of LinodeCluster
284+
type LinodeClusterList struct {
285+
metav1.TypeMeta `json:",inline"`
286+
// metadata is the standard object's metadata.
287+
metav1.ListMeta `json:"metadata,omitempty"`
288+
// items is a list of LinodeCluster.
289+
Items []LinodeCluster `json:"items"`
290+
}
291+
292+
func init() {
293+
SchemeBuilder.Register(&LinodeCluster{}, &LinodeClusterList{})
294+
}

0 commit comments

Comments
 (0)