diff --git a/charts/rancher-turtles/templates/rancher-turtles-components.yaml b/charts/rancher-turtles/templates/rancher-turtles-components.yaml index de36e160c..aabfc45aa 100644 --- a/charts/rancher-turtles/templates/rancher-turtles-components.yaml +++ b/charts/rancher-turtles/templates/rancher-turtles-components.yaml @@ -1867,6 +1867,8 @@ rules: resources: - clusterregistrationtokens - clusterregistrationtokens/status + - clusters + - clusters/status verbs: - get - list diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 4b47323c4..6ccef6a76 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -153,6 +153,8 @@ rules: resources: - clusterregistrationtokens - clusterregistrationtokens/status + - clusters + - clusters/status verbs: - get - list diff --git a/internal/controllers/import_controller.go b/internal/controllers/import_controller.go index 12b756d31..7b8955eb7 100644 --- a/internal/controllers/import_controller.go +++ b/internal/controllers/import_controller.go @@ -231,6 +231,16 @@ func (r *CAPIImportReconciler) reconcileNormal(ctx context.Context, capiCluster return ctrl.Result{}, nil } + //log.Info("##### Creating management.cattle.io/v3 rancher cluster") + //if err := r.RancherClient.Create(ctx, &managementv3.Cluster{ + // ObjectMeta: metav1.ObjectMeta{ + // Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), + // Namespace: capiCluster.Namespace, + // }, + //}); err != nil { + // return ctrl.Result{}, fmt.Errorf("error creating management.cattle.io/v3 rancher cluster: %w", err) + //} + if err := r.RancherClient.Create(ctx, &provisioningv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), diff --git a/internal/controllers/import_controller_test.go b/internal/controllers/import_controller_test.go index 98d6a27c6..98c775b52 100644 --- a/internal/controllers/import_controller_test.go +++ b/internal/controllers/import_controller_test.go @@ -51,6 +51,7 @@ var _ = Describe("reconcile CAPI Cluster", func() { r *CAPIImportReconciler capiCluster *clusterv1.Cluster rancherCluster *provisioningv1.Cluster + rancherClusterV3 *managementv3.Cluster clusterRegistrationToken *managementv3.ClusterRegistrationToken capiKubeconfigSecret *corev1.Secret clusterName = "generated-rancher-cluster" @@ -78,6 +79,13 @@ var _ = Describe("reconcile CAPI Cluster", func() { }, } + rancherClusterV3 = &managementv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), + Namespace: testNamespace, + }, + } + clusterRegistrationToken = &managementv3.ClusterRegistrationToken{ ObjectMeta: metav1.ObjectMeta{ Name: clusterName, @@ -101,6 +109,7 @@ var _ = Describe("reconcile CAPI Cluster", func() { clientObjs := []client.Object{ capiCluster, rancherCluster, + rancherClusterV3, clusterRegistrationToken, capiKubeconfigSecret, } diff --git a/internal/rancher/management/v3/cluster.go b/internal/rancher/management/v3/cluster.go new file mode 100644 index 000000000..2fd6cd7d7 --- /dev/null +++ b/internal/rancher/management/v3/cluster.go @@ -0,0 +1,57 @@ +/* +Copyright © 2023 - 2024 SUSE LLC + +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 v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Cluster is the struct representing a Rancher Cluster. +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +type Cluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterSpec `json:"spec"` + Status ClusterStatus `json:"status,omitempty"` +} + +// ClusterSpec is the struct representing the specification of a Rancher Cluster. +type ClusterSpec struct { + DisplayName string `json:"displayName,omitempty"` + Description string `json:"description,omitempty"` +} + +// ClusterStatus is the struct representing the status of a Rancher Cluster. +type ClusterStatus struct { + ClusterName string `json:"clusterName,omitempty"` + AgentDeployed bool `json:"agentDeployed,omitempty"` + Ready bool `json:"ready,omitempty"` +} + +// ClusterList contains a list of ClusterList. +// +kubebuilder:object:root=true +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cluster `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Cluster{}, &ClusterList{}) +} diff --git a/internal/rancher/management/v3/zz_generated.deepcopy.go b/internal/rancher/management/v3/zz_generated.deepcopy.go index 179e2f7d9..eefdb9c9b 100644 --- a/internal/rancher/management/v3/zz_generated.deepcopy.go +++ b/internal/rancher/management/v3/zz_generated.deepcopy.go @@ -25,6 +25,65 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cluster) DeepCopyInto(out *Cluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. +func (in *Cluster) DeepCopy() *Cluster { + if in == nil { + return nil + } + out := new(Cluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterList) DeepCopyInto(out *ClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. +func (in *ClusterList) DeepCopy() *ClusterList { + if in == nil { + return nil + } + out := new(ClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterRegistrationToken) DeepCopyInto(out *ClusterRegistrationToken) { *out = *in @@ -113,3 +172,33 @@ func (in *ClusterRegistrationTokenStatus) DeepCopy() *ClusterRegistrationTokenSt in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +}