Skip to content

Commit 0f3a162

Browse files
committed
Add ROSAMachinePool CRD & Controller
This introduces basic support to create/delete ROSAMachinePools Lifecycle is captured in RosaMchinePoolReady condition - add cluster-template-rosa-machinepool.yaml
1 parent e63fee9 commit 0f3a162

12 files changed

+1114
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.12.1
7+
name: rosamachinepools.infrastructure.cluster.x-k8s.io
8+
spec:
9+
group: infrastructure.cluster.x-k8s.io
10+
names:
11+
categories:
12+
- cluster-api
13+
kind: ROSAMachinePool
14+
listKind: ROSAMachinePoolList
15+
plural: rosamachinepools
16+
shortNames:
17+
- rosamp
18+
singular: rosamachinepool
19+
scope: Namespaced
20+
versions:
21+
- additionalPrinterColumns:
22+
- description: MachinePool ready status
23+
jsonPath: .status.ready
24+
name: Ready
25+
type: string
26+
- description: Number of replicas
27+
jsonPath: .status.replicas
28+
name: Replicas
29+
type: integer
30+
name: v1beta2
31+
schema:
32+
openAPIV3Schema:
33+
description: ROSAMachinePool is the Schema for the rosamachinepools API.
34+
properties:
35+
apiVersion:
36+
description: 'APIVersion defines the versioned schema of this representation
37+
of an object. Servers should convert recognized schemas to the latest
38+
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
39+
type: string
40+
kind:
41+
description: 'Kind is a string value representing the REST resource this
42+
object represents. Servers may infer this from the endpoint the client
43+
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
44+
type: string
45+
metadata:
46+
type: object
47+
spec:
48+
description: RosaMachinePoolSpec defines the desired state of RosaMachinePool.
49+
properties:
50+
autoRepair:
51+
default: false
52+
description: AutoRepair specifies whether health checks should be
53+
enabled for machines in the NodePool. The default is false.
54+
type: boolean
55+
autoscaling:
56+
description: Autoscaling specifies auto scaling behaviour for this
57+
MachinePool. required if Replicas is not configured
58+
properties:
59+
maxReplicas:
60+
minimum: 1
61+
type: integer
62+
minReplicas:
63+
minimum: 1
64+
type: integer
65+
type: object
66+
availabilityZone:
67+
description: AvailabilityZone is an optinal field specifying the availability
68+
zone where instances of this machine pool should run For Multi-AZ
69+
clusters, you can create a machine pool in a Single-AZ of your choice.
70+
type: string
71+
instanceType:
72+
description: InstanceType specifies the AWS instance type
73+
type: string
74+
labels:
75+
additionalProperties:
76+
type: string
77+
description: Labels specifies labels for the Kubernetes node objects
78+
type: object
79+
nodePoolName:
80+
description: NodePoolName specifies the name of the nodepool in Rosa
81+
must be a valid DNS-1035 label, so it must consist of lower case
82+
alphanumeric and have a max length of 15 characters.
83+
maxLength: 15
84+
pattern: ^[a-z]([-a-z0-9]*[a-z0-9])?$
85+
type: string
86+
x-kubernetes-validations:
87+
- message: nodepoolName is immutable
88+
rule: self == oldSelf
89+
providerIDList:
90+
description: ProviderIDList contain a ProviderID for each machine
91+
instance that's currently managed by this machine pool.
92+
items:
93+
type: string
94+
type: array
95+
subnet:
96+
type: string
97+
required:
98+
- nodePoolName
99+
type: object
100+
status:
101+
description: RosaMachinePoolStatus defines the observed state of RosaMachinePool.
102+
properties:
103+
conditions:
104+
description: Conditions defines current service state of the managed
105+
machine pool
106+
items:
107+
description: Condition defines an observation of a Cluster API resource
108+
operational state.
109+
properties:
110+
lastTransitionTime:
111+
description: Last time the condition transitioned from one status
112+
to another. This should be when the underlying condition changed.
113+
If that is not known, then using the time when the API field
114+
changed is acceptable.
115+
format: date-time
116+
type: string
117+
message:
118+
description: A human readable message indicating details about
119+
the transition. This field may be empty.
120+
type: string
121+
reason:
122+
description: The reason for the condition's last transition
123+
in CamelCase. The specific API may choose whether or not this
124+
field is considered a guaranteed API. This field may not be
125+
empty.
126+
type: string
127+
severity:
128+
description: Severity provides an explicit classification of
129+
Reason code, so the users or machines can immediately understand
130+
the current situation and act accordingly. The Severity field
131+
MUST be set only when Status=False.
132+
type: string
133+
status:
134+
description: Status of the condition, one of True, False, Unknown.
135+
type: string
136+
type:
137+
description: Type of condition in CamelCase or in foo.example.com/CamelCase.
138+
Many .condition.type values are consistent across resources
139+
like Available, but because arbitrary conditions can be useful
140+
(see .node.status.conditions), the ability to deconflict is
141+
important.
142+
type: string
143+
required:
144+
- lastTransitionTime
145+
- status
146+
- type
147+
type: object
148+
type: array
149+
id:
150+
description: ID is the ID given by ROSA.
151+
type: string
152+
ready:
153+
default: false
154+
description: Ready denotes that the RosaMachinePool nodepool has joined
155+
the cluster
156+
type: boolean
157+
replicas:
158+
description: Replicas is the most recently observed number of replicas.
159+
format: int32
160+
type: integer
161+
required:
162+
- ready
163+
type: object
164+
type: object
165+
served: true
166+
storage: true
167+
subresources:
168+
status: {}

config/crd/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ resources:
2323
- bases/bootstrap.cluster.x-k8s.io_eksconfigtemplates.yaml
2424
- bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml
2525
- bases/infrastructure.cluster.x-k8s.io_rosaclusters.yaml
26+
- bases/infrastructure.cluster.x-k8s.io_rosamachinepools.yaml
2627
# +kubebuilder:scaffold:crdkustomizeresource
2728

2829
patchesStrategicMerge:

config/rbac/role.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,22 @@ rules:
378378
- get
379379
- patch
380380
- update
381+
- apiGroups:
382+
- infrastructure.cluster.x-k8s.io
383+
resources:
384+
- rosamachinenepools
385+
verbs:
386+
- delete
387+
- get
388+
- list
389+
- patch
390+
- update
391+
- watch
392+
- apiGroups:
393+
- infrastructure.cluster.x-k8s.io
394+
resources:
395+
- rosamachinenepools/status
396+
verbs:
397+
- get
398+
- patch
399+
- update

exp/api/v1beta2/conditions_consts.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,11 @@ const (
102102
// reconciling EKS nodegroup iam roles.
103103
IAMFargateRolesReconciliationFailedReason = "IAMFargateRolesReconciliationFailed"
104104
)
105+
106+
const (
107+
// RosaMachinePoolReadyCondition condition reports on the successful reconciliation of rosa control plane.
108+
RosaMachinePoolReadyCondition clusterv1.ConditionType = "RosaMchinePoolReady"
109+
// WaitingForRosaControlPlaneReason used when the machine pool is waiting for
110+
// ROSA control plane infrastructure to be ready before proceeding.
111+
WaitingForRosaControlPlaneReason = "WaitingForRosaControlPlane"
112+
)

exp/api/v1beta2/finalizers.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ const (
2525

2626
// ManagedMachinePoolFinalizer allows the controller to clean up resources on delete.
2727
ManagedMachinePoolFinalizer = "awsmanagedmachinepools.infrastructure.cluster.x-k8s.io"
28+
29+
// RosaMachinePoolFinalizer allows the controller to clean up resources on delete.
30+
RosaMachinePoolFinalizer = "rosamachinepools.infrastructure.cluster.x-k8s.io"
2831
)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
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 v1beta2
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
22+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
23+
)
24+
25+
// RosaMachinePoolSpec defines the desired state of RosaMachinePool.
26+
type RosaMachinePoolSpec struct {
27+
// NodePoolName specifies the name of the nodepool in Rosa
28+
// must be a valid DNS-1035 label, so it must consist of lower case alphanumeric and have a max length of 15 characters.
29+
//
30+
// +immutable
31+
// +kubebuilder:validation:XValidation:rule="self == oldSelf", message="nodepoolName is immutable"
32+
// +kubebuilder:validation:MaxLength:=15
33+
// +kubebuilder:validation:Pattern:=`^[a-z]([-a-z0-9]*[a-z0-9])?$`
34+
NodePoolName string `json:"nodePoolName"`
35+
36+
// AvailabilityZone is an optinal field specifying the availability zone where instances of this machine pool should run
37+
// For Multi-AZ clusters, you can create a machine pool in a Single-AZ of your choice.
38+
// +optional
39+
AvailabilityZone string `json:"availabilityZone,omitempty"`
40+
41+
// +optional
42+
Subnet string `json:"subnet,omitempty"`
43+
44+
// Labels specifies labels for the Kubernetes node objects
45+
// +optional
46+
Labels map[string]string `json:"labels,omitempty"`
47+
48+
// AutoRepair specifies whether health checks should be enabled for machines
49+
// in the NodePool. The default is false.
50+
// +optional
51+
// +kubebuilder:default=false
52+
AutoRepair bool `json:"autoRepair,omitempty"`
53+
54+
// InstanceType specifies the AWS instance type
55+
InstanceType string `json:"instanceType,omitempty"`
56+
57+
// Autoscaling specifies auto scaling behaviour for this MachinePool.
58+
// required if Replicas is not configured
59+
// +optional
60+
Autoscaling *RosaMachinePoolAutoScaling `json:"autoscaling,omitempty"`
61+
62+
// TODO(alberto): Enable and propagate this API input.
63+
// Taints []*Taint `json:"taints,omitempty"`
64+
// TuningConfigs []string `json:"tuningConfigs,omitempty"`
65+
// Version *Version `json:"version,omitempty"`
66+
67+
// ProviderIDList contain a ProviderID for each machine instance that's currently managed by this machine pool.
68+
// +optional
69+
ProviderIDList []string `json:"providerIDList,omitempty"`
70+
}
71+
72+
// RosaMachinePoolAutoScaling specifies scaling options.
73+
type RosaMachinePoolAutoScaling struct {
74+
// +kubebuilder:validation:Minimum=1
75+
MinReplicas int `json:"minReplicas,omitempty"`
76+
// +kubebuilder:validation:Minimum=1
77+
MaxReplicas int `json:"maxReplicas,omitempty"`
78+
}
79+
80+
// RosaMachinePoolStatus defines the observed state of RosaMachinePool.
81+
type RosaMachinePoolStatus struct {
82+
// Ready denotes that the RosaMachinePool nodepool has joined
83+
// the cluster
84+
// +kubebuilder:default=false
85+
Ready bool `json:"ready"`
86+
87+
// Replicas is the most recently observed number of replicas.
88+
// +optional
89+
Replicas int32 `json:"replicas"`
90+
91+
// Conditions defines current service state of the managed machine pool
92+
// +optional
93+
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
94+
95+
// ID is the ID given by ROSA.
96+
ID string `json:"id,omitempty"`
97+
}
98+
99+
// +kubebuilder:object:root=true
100+
// +kubebuilder:resource:path=rosamachinepools,scope=Namespaced,categories=cluster-api,shortName=rosamp
101+
// +kubebuilder:storageversion
102+
// +kubebuilder:subresource:status
103+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="MachinePool ready status"
104+
// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Number of replicas"
105+
106+
// ROSAMachinePool is the Schema for the rosamachinepools API.
107+
type ROSAMachinePool struct {
108+
metav1.TypeMeta `json:",inline"`
109+
metav1.ObjectMeta `json:"metadata,omitempty"`
110+
111+
Spec RosaMachinePoolSpec `json:"spec,omitempty"`
112+
Status RosaMachinePoolStatus `json:"status,omitempty"`
113+
}
114+
115+
// +kubebuilder:object:root=true
116+
117+
// ROSAMachinePoolList contains a list of RosaMachinePools.
118+
type ROSAMachinePoolList struct {
119+
metav1.TypeMeta `json:",inline"`
120+
metav1.ListMeta `json:"metadata,omitempty"`
121+
Items []ROSAMachinePool `json:"items"`
122+
}
123+
124+
// GetConditions returns the observations of the operational state of the RosaMachinePool resource.
125+
func (r *ROSAMachinePool) GetConditions() clusterv1.Conditions {
126+
return r.Status.Conditions
127+
}
128+
129+
// SetConditions sets the underlying service state of the RosaMachinePool to the predescribed clusterv1.Conditions.
130+
func (r *ROSAMachinePool) SetConditions(conditions clusterv1.Conditions) {
131+
r.Status.Conditions = conditions
132+
}
133+
134+
func init() {
135+
SchemeBuilder.Register(&ROSAMachinePool{}, &ROSAMachinePoolList{})
136+
}

0 commit comments

Comments
 (0)