Skip to content

Commit

Permalink
Merge pull request #863 from salasberryfin/clusterclass-operations-sc…
Browse files Browse the repository at this point in the history
…affold

feat: add clusterclass exp feature scaffolding
  • Loading branch information
salasberryfin authored Jan 3, 2025
2 parents f15f859 + 3947ffb commit 359128c
Show file tree
Hide file tree
Showing 37 changed files with 3,041 additions and 43 deletions.
46 changes: 46 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ TEST_DIR := test
TOOLS_DIR := hack/tools
TOOLS_BIN_DIR := $(abspath $(TOOLS_DIR)/$(BIN_DIR))
EXP_ETCDRESTORE_DIR := exp/etcdrestore
EXP_CLUSTERCLASS_DIR := exp/clusterclass

$(TOOLS_BIN_DIR):
mkdir -p $@
Expand Down Expand Up @@ -184,6 +185,10 @@ CONTROLLER_IMG ?= $(REGISTRY)/$(ORG)/$(CONTROLLER_IMAGE_NAME)
CONTROLLER_IMAGE_VERSION ?= $(shell git describe --abbrev=0 2>/dev/null)
IID_FILE ?= $(shell mktemp)

# clusterclass
CLUSTERCLASS_IMAGE_NAME ?= turtles-clusterclass-operations
CLUSTERCLASS_IMG ?= $(REGISTRY)/$(ORG)/$(CLUSTERCLASS_IMAGE_NAME)

# Release
# Exclude tags with the prefix 'test/'
RELEASE_TAG ?= $(shell git describe --abbrev=0 --exclude 'test/*' 2>/dev/null)
Expand Down Expand Up @@ -261,11 +266,19 @@ generate-exp-etcdrestore-manifests-api: controller-gen ## Generate ClusterRole a
output:webhook:dir=./exp/etcdrestore/config/webhook \
webhook

.PHONY: generate-exp-clusterclass-manifests-api
generate-exp-clusterclass-manifests-api: controller-gen ## Generate ClusterRole and CustomResourceDefinition objects for experimental API.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd paths="./exp/clusterclass/api/v1alpha1/..." \
paths=./exp/clusterclass/internal/controller/... \
output:crd:artifacts:config=./exp/clusterclass/config/crd/bases \
output:rbac:dir=./exp/clusterclass/config/rbac

.PHONY: generate-modules
generate-modules: ## Run go mod tidy to ensure modules are up to date
go mod tidy
cd $(TEST_DIR); go mod tidy
cd $(EXP_ETCDRESTORE_DIR); go mod tidy
cd $(EXP_CLUSTERCLASS_DIR); go mod tidy

.PHONY: generate-go-deepcopy
generate-go-deepcopy: ## Run deepcopy generation
Expand Down Expand Up @@ -332,6 +345,10 @@ test: $(SETUP_ENVTEST) manifests test-exp-etcdrestore ## Run all generators and
test-exp-etcdrestore: $(SETUP_ENVTEST) ## Run tests for experimental etcdrestore API.
cd $(EXP_ETCDRESTORE_DIR); KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS)

.PHONY: test-exp-clusterclass
test-exp-clusterclass: $(SETUP_ENVTEST) ## Run tests for experimental clusterclass API.
cd $(EXP_CLUSTERCLASS_DIR); KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS)

##@ Build

.PHONY: build
Expand Down Expand Up @@ -384,6 +401,35 @@ docker-build-and-push: buildx-machine docker-pull-prerequisites ## Run docker-bu
--build-arg package=. \
--build-arg ldflags="$(LDFLAGS)" . -t $(CONTROLLER_IMG):$(TAG)

## --------------------------------------
## Docker - clusterclass
## --------------------------------------

.PHONY: docker-build-clusterclass ## Build the docker image for clusterclass
docker-build-clusterclass: buildx-machine docker-pull-prerequisites ## Build docker image for a specific architecture
## reads Dockerfile from stdin to avoid an incorrectly cached Dockerfile (https://github.com/moby/buildkit/issues/1368)
# buildx does not support using local registry for multi-architecture images
cat $(EXP_CLUSTERCLASS_DIR)/Dockerfile | DOCKER_BUILDKIT=1 BUILDX_BUILDER=$(MACHINE) docker buildx build $(ADDITIONAL_COMMANDS) \
--platform $(ARCH) \
--load \
--build-arg builder_image=$(GO_CONTAINER_IMAGE) \
--build-arg goproxy=$(GOPROXY) \
--build-arg package=./exp/clusterclass \
--build-arg ldflags="$(LDFLAGS)" . -t $(CLUSTERCLASS_IMG):$(TAG) --file - --progress=plain

.PHONY: docker-build-and-push-clusterclass
docker-build-and-push-clusterclass: buildx-machine docker-pull-prerequisites ## Run docker-build-and-push-clusterclass targets for all architectures
cat $(EXP_CLUSTERCLASS_DIR)/Dockerfile | DOCKER_BUILDKIT=1 BUILDX_BUILDER=$(MACHINE) docker buildx build $(ADDITIONAL_COMMANDS) \
--platform $(TARGET_PLATFORMS) \
--push \
--sbom=true \
--attest type=provenance,mode=max \
--iidfile=$(IID_FILE) \
--build-arg builder_image=$(GO_CONTAINER_IMAGE) \
--build-arg goproxy=$(GOPROXY) \
--build-arg package=./exp/clusterclass \
--build-arg ldflags="$(LDFLAGS)" . -t $(CLUSTERCLASS_IMG):$(TAG) --file - --progress=plain

docker-list-all:
@echo $(CONTROLLER_IMG):${TAG}

Expand Down
16 changes: 14 additions & 2 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if settings.get("trigger_mode") == "manual":
if settings.get("default_registry") != "":
default_registry(settings.get("default_registry"))

always_enable_projects = ["turtles", "turtles-capiproviders", "turtles-etcdsnapshotrestore"]
always_enable_projects = ["turtles", "turtles-capiproviders", "turtles-etcdsnapshotrestore", "turtles-clusterclass-operations"]

projects = {
"turtles": {
Expand Down Expand Up @@ -74,6 +74,18 @@ projects = {
"kustomize_dir": "config/capiproviders",
"label": "turtles-capiproviders",
"op": "apply"
},
"turtles-clusterclass-operations": {
"context": "exp/clusterclass",
"image": "ghcr.io/rancher/turtles-clusterclass-operations:dev",
"live_reload_deps": [
"main.go",
"go.mod",
"go.sum",
"internal/",
],
"kustomize_dir": "config/default",
"label": "turtles-clusterclass-operations"
}
}

Expand Down Expand Up @@ -101,4 +113,4 @@ def get_projects():

include_user_tilt_files()

enable_projects()
enable_projects()
133 changes: 133 additions & 0 deletions exp/clusterclass/api/v1alpha1/clusterupgradegroup_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
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"
"k8s.io/apimachinery/pkg/util/intstr"
)

// ClusterUpgradeGroupSpec defines the desired state of ClusterUpgradeGroup
type ClusterUpgradeGroupSpec struct {
// +required
ClassName string `json:"className"`

// RolloutStrategy controls the rollout of bundles, by defining
// partitions, canaries and percentages for cluster availability.
// +optional
RolloutStrategy *RolloutStrategy `json:"rolloutStrategy,omitempty"`

// Targets refer to the clusters that should be upgraded.
Targets []ClusterTargets `json:"targets,omitempty"`
}

type RolloutStrategyType string

const (
// RollingUpdateStrategyType updates clusters by using rolling update
RollingUpdateStrategyType RolloutStrategyType = "RollingUpdate"
)

// RolloutStrategy describes how to replace existing machines
// with new ones.
type RolloutStrategy struct {
// Type of rollout.
// Default is RollingUpdate.
// +optional
Type RolloutStrategyType `json:"type,omitempty"`

// Rolling update config params. Present only if
// RolloutStrategyType = RollingUpdate.
// +optional
RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"`
}

// RollingUpdate is used to control the desired behavior of rolling update.
type RollingUpdate struct {
// The maximum number of clusters that can be in update state (non-active) during a
// rolling update.
// +optional
MaxRollouts *intstr.IntOrString `json:"maxRollouts,omitempty"`
// The delay between subsequent cluster rollouts.
// +optional
RolloutDelay *intstr.IntOrString `json:"rolloutDelay,omitempty"`
// The maximum number of failed attempts before skipping the update for a given
// cluster.
// +optional
MaxFailures *intstr.IntOrString `json:"maxFailures,omitempty"`
// NOTE: in future iterations we add a `FailureAction` field here to control the behavior
// The action to perform when a cluster rollout is considered a failure.
// Defaults is Skip.
// +optional
// FailureAction FailureActionType `json:"failureAction,omitempty"`
}

type ClusterTargets struct {
// Name of target. This value is largely for display and logging. If
// not specified a default name of the format "target000" will be used
Name string `json:"name,omitempty"`
// ClusterName to match a specific cluster by name that will be
// selected
// +nullable
ClusterName string `json:"clusterName,omitempty"`
// ClusterSelector is a selector to match clusters. The structure is
// the standard metav1.LabelSelector format. If clusterGroupSelector or
// clusterGroup is specified, clusterSelector will be used only to
// further refine the selection after clusterGroupSelector and
// clusterGroup is evaluated.
// +nullable
ClusterSelector *metav1.LabelSelector `json:"clusterSelector,omitempty"`
// ClusterGroup to match a specific cluster group by name.
// +nullable
ClusterGroup string `json:"clusterGroup,omitempty"`
// ClusterGroupSelector is a selector to match cluster groups.
// +nullable
ClusterGroupSelector *metav1.LabelSelector `json:"clusterGroupSelector,omitempty"`
// DoNotDeploy if set to true, will not deploy to this target.
DoNotDeploy bool `json:"doNotDeploy,omitempty"`
}

// ClusterUpgradeGroupStatus defines the observed state of ClusterUpgradeGroup
type ClusterUpgradeGroupStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

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

Spec ClusterUpgradeGroupSpec `json:"spec,omitempty"`
Status ClusterUpgradeGroupStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

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

func init() {
SchemeBuilder.Register(&ClusterUpgradeGroup{}, &ClusterUpgradeGroupList{})
}
36 changes: 36 additions & 0 deletions exp/clusterclass/api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
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 contains API Schema definitions for the rollout v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=rollout.turtles-capi.cattle.io
package v1alpha1

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "rollout.turtles-capi.cattle.io", Version: "v1alpha1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
Loading

0 comments on commit 359128c

Please sign in to comment.