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

Add k0s+aws template with bootstrapped control planes #13

Closed
wants to merge 19 commits into from
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
kubeconfig
# Binaries for programs and plugins
bin
dist
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build the manager binary
FROM golang:1.21 AS builder
FROM golang:1.22 AS builder
ARG TARGETOS
ARG TARGETARCH

Expand All @@ -14,7 +14,7 @@ RUN go mod download
# Copy the go source
COPY cmd/main.go cmd/main.go
COPY api/ api/
COPY internal/controller/ internal/controller/
COPY internal/ internal/

# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
Expand Down
148 changes: 129 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
NAMESPACE ?= hmc-system
# Image URL to use all building/pushing image targets
IMG ?= controller:latest
IMG ?= hmc/controller:latest
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.29.0

Expand Down Expand Up @@ -51,6 +52,14 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: hmc-chart-generate
hmc-chart-generate: kustomize helmify ## Generate hmc helm chart
rm -rf charts/hmc/values.yaml charts/hmc/templates/*.yaml
$(KUSTOMIZE) build config/default | $(HELMIFY) charts/hmc

.PHONY: generate-all
generate-all: generate manifests hmc-chart-generate

.PHONY: fmt
fmt: ## Run go fmt against code.
go fmt ./...
Expand All @@ -60,7 +69,7 @@ vet: ## Run go vet against code.
go vet ./...

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
test: generate-all fmt vet envtest external-crd ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out

# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
Expand All @@ -78,12 +87,27 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes

##@ Build

TEMPLATES_DIR := templates
CHARTS_PACKAGE_DIR ?= $(LOCALBIN)/charts
$(CHARTS_PACKAGE_DIR): $(LOCALBIN)
rm -rf $(CHARTS_PACKAGE_DIR)
mkdir -p $(CHARTS_PACKAGE_DIR)
CHARTS = $(patsubst $(TEMPLATES_DIR)/%,%,$(wildcard $(TEMPLATES_DIR)/*))

helm-package: $(patsubst %,package-chart-%,$(CHARTS))

lint-chart-%:
$(HELM) lint --strict $(TEMPLATES_DIR)/$*

package-chart-%: $(CHARTS_PACKAGE_DIR) lint-chart-%
$(HELM) package --destination $(CHARTS_PACKAGE_DIR) $(TEMPLATES_DIR)/$*

.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
build: generate-all fmt vet ## Build manager binary.
go build -o bin/manager cmd/main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
run: generate-all fmt vet ## Run a controller from your host.
go run ./cmd/main.go

# If you wish to build the manager image targeting other platforms you can use the --platform flag.
Expand Down Expand Up @@ -115,50 +139,114 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
rm Dockerfile.cross

.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
build-installer: generate-all kustomize ## Generate a consolidated YAML with CRDs and deployment.
mkdir -p dist
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default > dist/install.yaml

.PHONY: hmc-chart-generate
hmc-chart-generate: kustomize helmify ## Generate hmc helm chart
rm -rf charts/hmc/values.yaml charts/hmc/templates/*.yaml
$(KUSTOMIZE) build config/default | $(HELMIFY) charts/hmc

##@ Deployment

KIND_CLUSTER_NAME ?= hmc-dev
KIND_NETWORK ?= kind
LOCAL_REGISTRY_NAME ?= hmc-local-registry
LOCAL_REGISTRY_PORT ?= 5001
LOCAL_REGISTRY_REPO ?= oci://127.0.0.1:$(LOCAL_REGISTRY_PORT)/chart

ifndef ignore-not-found
ignore-not-found = false
endif

.PHONY: deploy-helm-controller
deploy-helm-controller: helm
$(HELM) upgrade --install --set $(FLUX_CHART_VALUES) helm-controller $(FLUX_CHART_REPOSITORY) --version $(FLUX_CHART_VERSION) -n hmc-system

.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
.PHONY: kind-deploy
kind-deploy: kind
@if ! $(KIND) get clusters | grep -q "^$(KIND_CLUSTER_NAME)$$"; then \
kind create cluster -n $(KIND_CLUSTER_NAME); \
fi

.PHONY: kind-undeploy
kind-undeploy: kind
@if kind get clusters | grep -q "^$(KIND_CLUSTER_NAME)$$"; then \
kind delete cluster --name $(KIND_CLUSTER_NAME); \
fi

.PHONY: registry-deploy
registry-deploy:
@if [ ! "$$($(CONTAINER_TOOL) ps -aq -f name=$(LOCAL_REGISTRY_NAME))" ]; then \
echo "Starting new local registry container $(LOCAL_REGISTRY_NAME)"; \
$(CONTAINER_TOOL) run -d --restart=always -p "127.0.0.1:$(LOCAL_REGISTRY_PORT):5000" --network bridge --name "$(LOCAL_REGISTRY_NAME)" registry:2; \
fi; \
if [ "$$($(CONTAINER_TOOL) inspect -f='{{json .NetworkSettings.Networks.$(KIND_NETWORK)}}' $(LOCAL_REGISTRY_NAME))" = 'null' ]; then \
$(CONTAINER_TOOL) network connect $(KIND_NETWORK) $(LOCAL_REGISTRY_NAME); \
fi

.PHONY: registry-undeploy
registry-undeploy:
@if [ "$$($(CONTAINER_TOOL) ps -aq -f name=$(LOCAL_REGISTRY_NAME))" ]; then \
echo "Removing local registry container $(LOCAL_REGISTRY_NAME)"; \
$(CONTAINER_TOOL) rm -f "$(LOCAL_REGISTRY_NAME)"; \
fi

.PHONY: helm-controller-deploy
helm-controller-deploy: helm
$(HELM) upgrade --install --create-namespace --set $(FLUX_CHART_VALUES) helm-controller $(FLUX_CHART_REPOSITORY) --version $(FLUX_CHART_VERSION) -n $(NAMESPACE)

.PHONY: crd-install
crd-install: generate-all kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

.PHONY: uninstall
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
.PHONY: crd-uninstall
crd-uninstall: generate-all kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
deploy: generate-all kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -

.PHONY: undeploy
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: dev-deploy
dev-deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/dev | $(KUBECTL) apply -f -

.PHONY: dev-undeploy
dev-undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/dev | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: dev-push
dev-push: docker-build helm-package
$(KIND) load docker-image $(IMG) -n $(KIND_CLUSTER_NAME)
@for chart in $(CHARTS_PACKAGE_DIR)/*.tgz; do \
echo "Pushing $$chart to $(LOCAL_REGISTRY_REPO)"; \
$(HELM) push "$$chart" $(LOCAL_REGISTRY_REPO); \
done

.PHONY: dev-apply
dev-apply: kind-deploy crd-install registry-deploy helm-controller-deploy dev-push dev-deploy
kubectl rollout restart -n $(NAMESPACE) deployment/hmc-controller-manager

.PHONY: dev-destroy
dev-destroy: kind-undeploy registry-undeploy

##@ Dependencies

## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
mkdir -p $(LOCALBIN)

EXTERNAL_CRD_DIR ?= $(LOCALBIN)/crd
$(EXTERNAL_CRD_DIR): $(LOCALBIN)
mkdir -p $(EXTERNAL_CRD_DIR)

FLUX_SOURCE_VERSION ?= $(shell go mod edit -json | jq -r '.Require[] | select(.Path == "github.com/fluxcd/source-controller/api") | .Version')
FLUX_SOURCE_REPO_CRD ?= $(EXTERNAL_CRD_DIR)/source-helmrepositories-$(FLUX_SOURCE_VERSION).yaml
FLUX_SOURCE_CHART_CRD ?= $(EXTERNAL_CRD_DIR)/source-helmchart-$(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

## Tool Binaries
KUBECTL ?= kubectl
KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION)
Expand All @@ -167,6 +255,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION)
GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
HELM ?= $(LOCALBIN)/helm-$(HELM_VERSION)
HELMIFY ?= $(LOCALBIN)/helmify-$(HELMIFY_VERSION)
KIND ?= $(LOCALBIN)/kind-$(KIND_VERSION)

FLUX_CHART_REPOSITORY ?= oci://ghcr.io/fluxcd-community/charts/flux2
FLUX_CHART_VERSION ?= 2.13.0
Expand All @@ -179,6 +268,7 @@ ENVTEST_VERSION ?= release-0.17
GOLANGCI_LINT_VERSION ?= v1.57.2
HELM_VERSION ?= v3.15.1
HELMIFY_VERSION ?= v0.4.13
KIND_VERSION ?= v0.23.0

.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
Expand Down Expand Up @@ -211,6 +301,26 @@ helmify: $(HELMIFY) ## Download helmify locally if necessary.
$(HELMIFY): $(LOCALBIN)
$(call go-install-tool,$(HELMIFY),github.com/arttor/helmify/cmd/helmify,${HELMIFY_VERSION})

.PHONY: kind
kind: $(KIND) ## Download kind locally if necessary.
$(KIND): $(LOCALBIN)
$(call go-install-tool,$(KIND),sigs.k8s.io/kind,${KIND_VERSION})

$(FLUX_HELM_CRD): $(EXTERNAL_CRD_DIR)
rm -f $(FLUX_HELM_CRD)
curl -s https://raw.githubusercontent.com/fluxcd/helm-controller/$(FLUX_HELM_VERSION)/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml > $(FLUX_HELM_CRD)

$(FLUX_SOURCE_CHART_CRD): $(EXTERNAL_CRD_DIR)
rm -f $(FLUX_SOURCE_CHART_CRD)
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/$(FLUX_SOURCE_VERSION)/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml > $(FLUX_SOURCE_CHART_CRD)

$(FLUX_SOURCE_REPO_CRD): $(EXTERNAL_CRD_DIR)
rm -f $(FLUX_SOURCE_REPO_CRD)
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/$(FLUX_SOURCE_VERSION)/config/crd/bases/source.toolkit.fluxcd.io_helmrepositories.yaml > $(FLUX_SOURCE_REPO_CRD)

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

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary (ideally with version)
# $2 - package url which can be installed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ import (
// DeploymentSpec defines the desired state of Deployment
type DeploymentSpec struct {
// DryRun specifies whether the template should be applied after validation or only validated.
// +kubebuilder:validation:Optional
DryRun bool `json:"dryRun"`
// +optional
DryRun bool `json:"dryRun,omitempty"`
// Template is a reference to a Template object located in the same namespace.
// +kubebuilder:validation:Required
Template string `json:"template"`
// Configuration allows to provide parameters for template customization.
// If no Configuration provided, the field will be populated with the default values for
// the template and DryRun will be enabled.
// +kubebuilder:validation:Optional
Configuration apiextensionsv1.JSON `json:"configuration"`
// +optional
Configuration apiextensionsv1.JSON `json:"configuration,omitempty"`
}

// DeploymentStatus defines the observed state of Deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ limitations under the License.
package v1alpha1

import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

helmcontrollerv2 "github.com/fluxcd/helm-controller/api/v2"
)

const (
// TemplateKind is the string representation of a Template.
TemplateKind = "Template"
)

// TemplateSpec defines the desired state of Template
Expand All @@ -26,25 +34,45 @@ type TemplateSpec struct {
// +kubebuilder:validation:Enum=aws
// +kubebuilder:validation:Required
Provider string `json:"provider"`
// HelmChartURL is a URL of the helm chart representing the template.
// Helm holds a reference to a Helm chart representing the HMC template
// +kubebuilder:validation:Required
HelmChartURL string `json:"helmChartURL"`
Helm HelmSpec `json:"helm"`
}

// +kubebuilder:validation:XValidation:rule="(has(self.chartName) && !has(self.chartRef)) || (!has(self.chartName) && has(self.chartRef))", message="either chartName or chartRef must be set"

// HelmSpec references a Helm chart representing the HMC template
type HelmSpec struct {
// ChartName is a name of a Helm chart representing the template in the HMC repository.
// +optional
ChartName string `json:"chartName,omitempty"`
// ChartVersion is a version of a Helm chart representing the template in the HMC repository.
// +optional
ChartVersion string `json:"chartVersion,omitempty"`
// ChartRef is a reference to a source controller resource containing the
// Helm chart representing the template.
// +optional
ChartRef *helmcontrollerv2.CrossNamespaceSourceReference `json:"chartRef,omitempty"`
}

// TemplateStatus defines the observed state of Template
type TemplateStatus struct {
TemplateValidationStatus `json:",inline"`
// Descriptions contains information about the template.
// +optional
Description string `json:"description"`
Description string `json:"description,omitempty"`
// Configuration demonstrates available parameters for template customization,
// that can be used when creating Deployment objects.
// +optional
Configuration apiextensionsv1.JSON `json:"configuration,omitempty"`
}

type TemplateValidationStatus struct {
// Valid indicates whether the template passed validation or not.
Valid bool `json:"valid"`
// ValidationError provides information regarding issues encountered during template validation.
// +optional
ValidationError string `json:"validationError"`
ValidationError string `json:"validationError,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
Loading
Loading