Skip to content

Commit

Permalink
feat: add support for cluster class
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Salas <[email protected]>
  • Loading branch information
salasberryfin committed Feb 12, 2024
1 parent a6238db commit 49fcc9d
Show file tree
Hide file tree
Showing 27 changed files with 2,154 additions and 149 deletions.
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ issues:
linters:
- dupl
- wrapcheck
- lll
- text: var-naming
linters:
- revive
Expand Down
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,62 @@ To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

:tada: CONGRATULATIONS ! :tada: You created your first RKE2 cluster with CAPD as an infrastructure provider.

### Using ClusterClass for cluster creation

This provider supports using [ClusterClass](https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210526-cluster-class-and-managed-topologies.md), a Cluster API feature that implements an extra level of abstraction on top of the existing Cluster API functionality. The `ClusterClass` object is used to define a collection of template resources (control plane and machine deployment) which are used to generate one or more clusters of the same flavor.

If you are interested in leveraging this functionality, you can refer to the examples [here](./samples/docker/clusterclass/):
- [clusterclass-quick-start.yaml](./samples/docker/clusterclass/clusterclass-quick-start.yaml): creates a sample `ClusterClass` and necessary resources.
- [rke2-sample.yaml](./samples/docker/clusterclass/rke2-sample.yaml): creates a workload cluster using the `ClusterClass`.

As with other sample templates, you will need to set a number environment variables:
- CLUSTER_NAME
- CABPR_CP_REPLICAS
- CABPR_WK_REPLICAS
- KUBERNETES_VERSION
- KIND_IP

for example :

```bash
export CLUSTER_NAME=capd-rke2-clusterclass
export CABPR_CP_REPLICAS=3
export CABPR_WK_REPLICAS=2
export KUBERNETES_VERSION=v1.25.11
export KIND_IP=192.168.20.20
```

**Remember that, since we are using Kind, the value of `KIND_IP` must be an IP address in the range of the `kind` network.**
You can check the range Docker assigns to this network by inspecting it:

```bash
docker network inspect kind
```

The next step is to substitue the values in the YAML using the following commands:

```bash
cat clusterclass-quick-start.yaml | clusterctl generate yaml > clusterclass-example.yaml
```

At this moment, you can take some time to study the resulting YAML, then you can apply it to the management cluster:

```bash
kubectl apply -f clusterclass-example.yaml
```

This will create a new `ClusterClass` template that can be used to provision one or multiple workload clusters of the same flavor.
To do so, you can follow the same procedure and substitute the values in the YAML for the cluster definition:

```bash
cat rke2-sample.yaml | clusterctl generate yaml > rke2-clusterclass-example.yaml
```

And then apply the resulting YAML file to create a cluster from the existing `ClusterClass`.
```bash
kubectl apply -f rke2-clusterclass-example.yaml
```

## Testing the DEV main branch
These instructions are for development purposes initially and will be changed in the future for user facing instructions.

Expand Down
1 change: 1 addition & 0 deletions bootstrap/api/v1beta1/rke2config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ type RKE2AgentConfig struct {
LoadBalancerPort int `json:"loadBalancerPort,omitempty"`

// Version specifies the rke2 version.
// This field will be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version will be used instead.
//+optional
Version string `json:"version,omitempty"`

Expand Down
4 changes: 2 additions & 2 deletions bootstrap/api/v1beta1/rke2config_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (r *RKE2Config) SetupWebhookWithManager(mgr ctrl.Manager) error {
Complete()
}

//+kubebuilder:webhook:path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-rke2config,mutating=true,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configs,verbs=create;update,versions=v1beta1,name=mrke2config.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-rke2config,mutating=true,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configs,verbs=create;update,versions=v1beta1,name=mrke2config.kb.io,admissionReviewVersions=v1;v1beta1

var _ webhook.Defaulter = &RKE2Config{}

Expand All @@ -60,7 +60,7 @@ func DefaultRKE2ConfigSpec(spec *RKE2ConfigSpec) {
}
}

//+kubebuilder:webhook:path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-rke2config,mutating=false,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configs,verbs=create;update,versions=v1beta1,name=vrke2config.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-rke2config,mutating=false,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configs,verbs=create;update,versions=v1beta1,name=vrke2config.kb.io,admissionReviewVersions=v1;v1beta1

var _ webhook.Validator = &RKE2Config{}

Expand Down
4 changes: 2 additions & 2 deletions bootstrap/api/v1beta1/rke2configtemplate_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (r *RKE2ConfigTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
Complete()
}

//+kubebuilder:webhook:path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-rke2configtemplate,mutating=true,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configtemplates,verbs=create;update,versions=v1beta1,name=mrke2configtemplate.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/mutate-bootstrap-cluster-x-k8s-io-v1beta1-rke2configtemplate,mutating=true,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configtemplates,verbs=create;update,versions=v1beta1,name=mrke2configtemplate.kb.io,admissionReviewVersions=v1;v1beta1

var _ webhook.Defaulter = &RKE2ConfigTemplate{}

Expand All @@ -43,7 +43,7 @@ func (r *RKE2ConfigTemplate) Default() {
RKE2configtemplatelog.Info("default", "name", r.Name)
}

//+kubebuilder:webhook:path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-rke2configtemplate,mutating=false,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configtemplates,verbs=create;update,versions=v1beta1,name=vrke2configtemplate.kb.io,admissionReviewVersions=v1
//+kubebuilder:webhook:path=/validate-bootstrap-cluster-x-k8s-io-v1beta1-rke2configtemplate,mutating=false,failurePolicy=fail,sideEffects=None,groups=bootstrap.cluster.x-k8s.io,resources=rke2configtemplates,verbs=create;update,versions=v1beta1,name=vrke2configtemplate.kb.io,admissionReviewVersions=v1;v1beta1

var _ webhook.Validator = &RKE2ConfigTemplate{}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,9 @@ spec:
for all system images.
type: string
version:
description: Version specifies the rke2 version.
description: Version specifies the rke2 version. This field will
be deprecated in newer versions of the API and RKE2ControlPlaneSpec.Version
will be used instead.
type: string
type: object
files:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,9 @@ spec:
be used for all system images.
type: string
version:
description: Version specifies the rke2 version.
description: Version specifies the rke2 version. This
field will be deprecated in newer versions of the API
and RKE2ControlPlaneSpec.Version will be used instead.
type: string
type: object
files:
Expand Down
1 change: 1 addition & 0 deletions bootstrap/config/crd/patches/webhook_in_rke2configs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ spec:
path: /convert
conversionReviewVersions:
- v1
- v1beta1
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ spec:
path: /convert
conversionReviewVersions:
- v1
- v1beta1
4 changes: 4 additions & 0 deletions bootstrap/config/webhook/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ metadata:
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
Expand All @@ -26,6 +27,7 @@ webhooks:
sideEffects: None
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
Expand All @@ -52,6 +54,7 @@ metadata:
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
Expand All @@ -72,6 +75,7 @@ webhooks:
sideEffects: None
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
Expand Down
61 changes: 60 additions & 1 deletion controlplane/api/v1alpha1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ package v1alpha1
import (
"fmt"

apiconversion "k8s.io/apimachinery/pkg/conversion"
utilconversion "sigs.k8s.io/cluster-api/util/conversion"

controlplanev1 "github.com/rancher-sandbox/cluster-api-provider-rke2/controlplane/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/conversion"
)
Expand All @@ -28,11 +31,20 @@ func (src *RKE2ControlPlane) ConvertTo(dstRaw conversion.Hub) error {
if !ok {
return fmt.Errorf("not a RKE2ControlPlane: %v", dst)
}

if err := Convert_v1alpha1_RKE2ControlPlane_To_v1beta1_RKE2ControlPlane(src, dst, nil); err != nil {
return err
}

// Manually restore data.
restored := &controlplanev1.RKE2ControlPlane{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}

dst.Spec.MachineTemplate = restored.Spec.MachineTemplate
dst.Spec.Version = restored.Spec.Version
dst.Status = restored.Status

return nil
}

Expand All @@ -46,6 +58,11 @@ func (dst *RKE2ControlPlane) ConvertFrom(srcRaw conversion.Hub) error {
return err
}

// Preserve Hub data on down-conversion
if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -85,6 +102,15 @@ func (src *RKE2ControlPlaneTemplate) ConvertTo(dstRaw conversion.Hub) error {
return err
}

// Manually restore data.
restored := &controlplanev1.RKE2ControlPlaneTemplate{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}

dst.Spec.Template = restored.Spec.Template
dst.Status = restored.Status

return nil
}

Expand All @@ -98,6 +124,11 @@ func (dst *RKE2ControlPlaneTemplate) ConvertFrom(srcRaw conversion.Hub) error {
return err
}

// Preserve Hub data on down-conversion
if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -126,3 +157,31 @@ func (dst *RKE2ControlPlaneTemplateList) ConvertFrom(srcRaw conversion.Hub) erro

return nil
}

func Convert_v1beta1_RKE2ControlPlaneSpec_To_v1alpha1_RKE2ControlPlaneSpec(in *controlplanev1.RKE2ControlPlaneSpec, out *RKE2ControlPlaneSpec, s apiconversion.Scope) error {
return autoConvert_v1beta1_RKE2ControlPlaneSpec_To_v1alpha1_RKE2ControlPlaneSpec(in, out, s)
}

func Convert_v1beta1_RKE2ControlPlaneStatus_To_v1alpha1_RKE2ControlPlaneStatus(in *controlplanev1.RKE2ControlPlaneStatus, out *RKE2ControlPlaneStatus, s apiconversion.Scope) error {
return autoConvert_v1beta1_RKE2ControlPlaneStatus_To_v1alpha1_RKE2ControlPlaneStatus(in, out, s)
}

func Convert_v1alpha1_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatus(in *RKE2ControlPlaneStatus, out *controlplanev1.RKE2ControlPlaneStatus, s apiconversion.Scope) error {
return autoConvert_v1alpha1_RKE2ControlPlaneStatus_To_v1beta1_RKE2ControlPlaneStatus(in, out, s)
}

func Convert_v1beta1_RKE2ControlPlaneTemplateSpec_To_v1alpha1_RKE2ControlPlaneTemplateSpec(in *controlplanev1.RKE2ControlPlaneTemplateSpec, out *RKE2ControlPlaneTemplateSpec, s apiconversion.Scope) error {
return autoConvert_v1beta1_RKE2ControlPlaneTemplateSpec_To_v1alpha1_RKE2ControlPlaneTemplateSpec(in, out, s)
}

func Convert_v1alpha1_RKE2ControlPlaneTemplateSpec_To_v1beta1_RKE2ControlPlaneTemplateSpec(in *RKE2ControlPlaneTemplateSpec, out *controlplanev1.RKE2ControlPlaneTemplateSpec, s apiconversion.Scope) error {
return autoConvert_v1alpha1_RKE2ControlPlaneTemplateSpec_To_v1beta1_RKE2ControlPlaneTemplateSpec(in, out, s)
}

func Convert_v1alpha1_RKE2ControlPlaneTemplateStatus_To_v1beta1_RKE2ControlPlaneStatus(in *RKE2ControlPlaneTemplateStatus, out *controlplanev1.RKE2ControlPlaneStatus, s apiconversion.Scope) error {
return nil
}

func Convert_v1beta1_RKE2ControlPlaneStatus_To_v1alpha1_RKE2ControlPlaneTemplateStatus(in *controlplanev1.RKE2ControlPlaneStatus, out *RKE2ControlPlaneTemplateStatus, s apiconversion.Scope) error {
return nil
}
3 changes: 0 additions & 3 deletions controlplane/api/v1alpha1/rke2controlplanetemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ import (
type RKE2ControlPlaneTemplateSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Foo is an example field of RKE2ControlPlaneTemplate. Edit rke2controlplanetemplate_types.go to remove/update
Foo string `json:"foo,omitempty"`
}

// RKE2ControlPlaneTemplateStatus defines the observed state of RKE2ControlPlaneTemplate.
Expand Down
Loading

0 comments on commit 49fcc9d

Please sign in to comment.