Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented the unmanaged cluster CRD for adopting existing k8s clusters #623

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,12 @@ FLUX_SOURCE_REPO_NAME ?= source-helmrepositories
FLUX_SOURCE_REPO_CRD ?= $(EXTERNAL_CRD_DIR)/$(FLUX_SOURCE_REPO_NAME)-$(FLUX_SOURCE_VERSION).yaml
FLUX_SOURCE_CHART_NAME ?= source-helmchart
FLUX_SOURCE_CHART_CRD ?= $(EXTERNAL_CRD_DIR)/$(FLUX_SOURCE_CHART_NAME)-$(FLUX_SOURCE_VERSION).yaml

FLUX_HELM_VERSION ?= $(shell go mod edit -json | jq -r '.Require[] | select(.Path == "github.com/fluxcd/helm-controller/api") | .Version')
FLUX_HELM_CRD ?= $(EXTERNAL_CRD_DIR)/helm-$(FLUX_HELM_VERSION).yaml
kylewuolle marked this conversation as resolved.
Show resolved Hide resolved
CAPI_VERSION ?= v1.8.4
CAPI_REPO_NAME ?= capi
CAPI_CRD ?= $(EXTERNAL_CRD_DIR)/$(CAPI_REPO_NAME)-$(CAPI_VERSION).yaml
FLUX_HELM_NAME ?= helm
FLUX_HELM_CRD ?= $(EXTERNAL_CRD_DIR)/$(FLUX_HELM_NAME)-$(FLUX_HELM_VERSION).yaml

SVELTOS_VERSION ?= v$(shell $(YQ) -r '.appVersion' $(PROVIDER_TEMPLATES_DIR)/projectsveltos/Chart.yaml)
SVELTOS_NAME ?= sveltos
Expand Down Expand Up @@ -479,8 +481,13 @@ $(SVELTOS_CRD): | yq $(EXTERNAL_CRD_DIR)
rm -f $(EXTERNAL_CRD_DIR)/$(SVELTOS_NAME)*
curl -s --fail https://raw.githubusercontent.com/projectsveltos/sveltos/$(SVELTOS_VERSION)/manifest/crds/sveltos_crds.yaml > $(SVELTOS_CRD)

$(CAPI_CRD): $(EXTERNAL_CRD_DIR)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$(CAPI_CRD): $(EXTERNAL_CRD_DIR)
$(CAPI_CRD): | $(EXTERNAL_CRD_DIR)

rm -f $(EXTERNAL_CRD_DIR)/$(CAPI_REPO_NAME)*
curl -s --fail https://raw.githubusercontent.com/kubernetes-sigs/cluster-api/$(CAPI_VERSION)/config/crd/bases/cluster.x-k8s.io_clusters.yaml > $(CAPI_CRD)
curl -s --fail https://raw.githubusercontent.com/kubernetes-sigs/cluster-api/$(CAPI_VERSION)/config/crd/bases/cluster.x-k8s.io_machines.yaml >> $(CAPI_CRD)

.PHONY: external-crd
external-crd: $(FLUX_HELM_CRD) $(FLUX_SOURCE_CHART_CRD) $(FLUX_SOURCE_REPO_CRD) $(SVELTOS_CRD)
external-crd: $(FLUX_HELM_CRD) $(FLUX_SOURCE_CHART_CRD) $(FLUX_SOURCE_REPO_CRD) $(SVELTOS_CRD) $(CAPI_CRD)

.PHONY: kind
kind: $(KIND) ## Download kind locally if necessary.
Expand Down
18 changes: 18 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,22 @@ resources:
kind: MultiClusterService
path: github.com/Mirantis/hmc/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: hmc.mirantis.com
group: hmc.mirantis.com
kind: UnmanagedCluster
path: github.com/Mirantis/hmc/api/v1alpha
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: hmc.mirantis.com
group: hmc.mirantis.com
kind: UnmanagedMachine
path: github.com/Mirantis/hmc/api/v1alpha1
version: v1alpha1
version: "3"
25 changes: 25 additions & 0 deletions api/v1alpha1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,28 @@ const (
// Provider Sveltos
ProviderSveltosName = "projectsveltos"
)

type ServicesType struct {
// Services is a list of services created via ServiceTemplates
// that could be installed on the target cluster.
Services []ServiceSpec `json:"services,omitempty"`

// +kubebuilder:default:=100
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2147483646
// ServicesPriority sets the priority for the services defined in this spec.
// Higher value means higher priority and lower means lower.
// In case of conflict with another object managing the service,
// the one with higher priority will get to deploy its services.
ServicesPriority int32 `json:"servicesPriority,omitempty"`
// DryRun specifies whether the template should be applied after validation or only validated.
// DryRun bool `json:"dryRun,omitempty"`

// +kubebuilder:default:=false

// StopOnConflict specifies what to do in case of a conflict.
// E.g. If another object is already managing a service.
// By default the remaining services will be deployed even if conflict is detected.
// If set to true, the deployment will stop after encountering the first conflict.
StopOnConflict bool `json:"stopOnConflict,omitempty"`
}
22 changes: 2 additions & 20 deletions api/v1alpha1/managedcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,29 +65,11 @@ type ManagedClusterSpec struct {
Template string `json:"template"`
// Name reference to the related Credentials object.
Credential string `json:"credential,omitempty"`
// Services is a list of services created via ServiceTemplates
// that could be installed on the target cluster.
Services []ServiceSpec `json:"services,omitempty"`

// +kubebuilder:default:=100
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2147483646

// ServicesPriority sets the priority for the services defined in this spec.
// Higher value means higher priority and lower means lower.
// In case of conflict with another object managing the service,
// the one with higher priority will get to deploy its services.
ServicesPriority int32 `json:"servicesPriority,omitempty"`

// DryRun specifies whether the template should be applied after validation or only validated.
DryRun bool `json:"dryRun,omitempty"`

// +kubebuilder:default:=false

// StopOnConflict specifies what to do in case of a conflict.
// E.g. If another object is already managing a service.
// By default the remaining services will be deployed even if conflict is detected.
// If set to true, the deployment will stop after encountering the first conflict.
StopOnConflict bool `json:"stopOnConflict,omitempty"`
ServicesType `json:",inline"`
}

// ManagedClusterStatus defines the observed state of ManagedCluster
Expand Down
22 changes: 1 addition & 21 deletions api/v1alpha1/multiclusterservice_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,7 @@ type ServiceSpec struct {
type MultiClusterServiceSpec struct {
// ClusterSelector identifies target clusters to manage services on.
ClusterSelector metav1.LabelSelector `json:"clusterSelector,omitempty"`
// Services is a list of services created via ServiceTemplates
// that could be installed on the target cluster.
Services []ServiceSpec `json:"services,omitempty"`

// +kubebuilder:default:=100
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2147483646

// ServicesPriority sets the priority for the services defined in this spec.
// Higher value means higher priority and lower means lower.
// In case of conflict with another object managing the service,
// the one with higher priority will get to deploy its services.
ServicesPriority int32 `json:"servicesPriority,omitempty"`

// +kubebuilder:default:=false

// StopOnConflict specifies what to do in case of a conflict.
// E.g. If another object is already managing a service.
// By default the remaining services will be deployed even if conflict is detected.
// If set to true, the deployment will stop after encountering the first conflict.
StopOnConflict bool `json:"stopOnConflict,omitempty"`
ServicesType `json:",inline"`
}

// ServiceStatus contains details for the state of services.
Expand Down
71 changes: 71 additions & 0 deletions api/v1alpha1/unmanagedcluster_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2024
//
// 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 v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
UnmanagedClusterKind = "UnmanagedCluster"
UnmanagedClusterFinalizer = "hmc.mirantis.com/unmanaged-cluster"
AllNodesCondition = "AllNodesCondition"
NodeCondition = "NodeCondition"
HelmChart = "HelmChart"
)

// UnmanagedClusterSpec defines the desired state of UnmanagedCluster
type UnmanagedClusterSpec struct {
ServicesType `json:",inline"`
}

// UnmanagedClusterStatus defines the observed state of UnmanagedCluster
type UnmanagedClusterStatus struct {
// Flag indicating whether the unmanaged cluster is in the ready state or not
// +kubebuilder:default:=false
Ready bool `json:"ready"`
kylewuolle marked this conversation as resolved.
Show resolved Hide resolved

// Conditions contains details for the current state of the ManagedCluster.
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:metadata:labels=cluster.x-k8s.io/v1beta1=v1alpha1
// UnmanagedCluster is the Schema for the unmanagedclusters API
type UnmanagedCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec UnmanagedClusterSpec `json:"spec,omitempty"`
Status UnmanagedClusterStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// UnmanagedClusterList contains a list of UnmanagedCluster
type UnmanagedClusterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []UnmanagedCluster `json:"items"`
}

func init() {
SchemeBuilder.Register(&UnmanagedCluster{}, &UnmanagedClusterList{})
}

func (in *UnmanagedCluster) GetConditions() *[]metav1.Condition {
return &in.Status.Conditions
}
66 changes: 66 additions & 0 deletions api/v1alpha1/unmanagedmachine_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024
//
// 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 v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// UnmanagedMachineSpec defines the desired state of UnmanagedMachine
type UnmanagedMachineSpec struct {
ProviderID string `json:"providerID,omitempty"`
ClusterName string `json:"clusterName,omitempty"`
ControlPlane bool `json:"controlPlane,omitempty"`
}

// UnmanagedMachineStatus defines the observed state of UnmanagedMachine
type UnmanagedMachineStatus struct {
// Flag indicating whether the machine is in the ready state or not
// +kubebuilder:default:=false
Ready bool `json:"ready,omitempty"`
kylewuolle marked this conversation as resolved.
Show resolved Hide resolved
// Conditions contains details for the current state of the ManagedCluster
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Machine ready status"
// +kubebuilder:metadata:labels=cluster.x-k8s.io/v1beta1=v1alpha1

// UnmanagedMachine is the Schema for the unmanagedmachines API
type UnmanagedMachine struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec UnmanagedMachineSpec `json:"spec,omitempty"`
Status UnmanagedMachineStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// UnmanagedMachineList contains a list of UnmanagedMachine
type UnmanagedMachineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []UnmanagedMachine `json:"items"`
}

func init() {
SchemeBuilder.Register(&UnmanagedMachine{}, &UnmanagedMachineList{})
}

func (in *UnmanagedMachine) GetConditions() *[]metav1.Condition {
return &in.Status.Conditions
}
Loading