diff --git a/Makefile b/Makefile index c0ac157..ff2d2fc 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ else GOBIN=$(shell go env GOBIN) endif +GOARCH := $(shell go env GOARCH) +GOOS := $(shell go env GOOS) + # CONTAINER_TOOL defines the container tool to be used for building images. # Be aware that the target commands are only tested with Docker which is # scaffolded by default. However, you might want to replace it to use other @@ -181,8 +184,12 @@ LOCALBIN ?= $(shell pwd)/bin $(LOCALBIN): mkdir -p $(LOCALBIN) +# curl retries +CURL_RETRIES=3 + ## Tool Binaries -KUBECTL ?= kubectl +KUBECTL ?= $(LOCALBIN)/kubectl-$(KUBECTL_VERSION) +KUBECTL_BIN ?= $(LOCALBIN)/kubectl KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION) CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION) ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION) @@ -192,6 +199,7 @@ GEN_CRD_API_REFERENCE_DOCS ?= $(LOCALBIN)/gen-crd-api-reference-docs-$(GEN_CRD_A ## Tool Versions KUSTOMIZE_VERSION ?= v5.3.0 +KUBECTL_VERSION ?= v1.29.4 CONTROLLER_TOOLS_VERSION ?= v0.15.0 ENVTEST_VERSION ?= latest GOLANGCI_LINT_VERSION ?= v1.60.1 @@ -203,6 +211,13 @@ kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. $(KUSTOMIZE): $(LOCALBIN) $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) +.PHONY: kubectl +kubectl: $(KUBECTL) ## Download kubectl locally if necessary. +$(KUBECTL): $(LOCALBIN) + curl --retry $(CURL_RETRIES) -fsL https://dl.k8s.io/release/$(KUBECTL_VERSION)/bin/$(GOOS)/$(GOARCH)/kubectl -o $(KUBECTL) + ln -sf "$(KUBECTL)" "$(KUBECTL_BIN)" + chmod +x "$(KUBECTL_BIN)" "$(KUBECTL)" + .PHONY: controller-gen controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. $(CONTROLLER_GEN): $(LOCALBIN) @@ -241,3 +256,26 @@ GOBIN=$(LOCALBIN) go install $${package} ;\ mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\ } endef + +## -------------------------------------- +## Tilt / Kind +## -------------------------------------- + +KIND_CLUSTER_NAME ?= metal + +.PHONY: kind-create +kind-create: $(KUBECTL) ## create metal kind cluster if needed + ./scripts/kind-with-registry.sh + +.PHONY: kind-delete +kind-delete: ## Destroys the "metal" kind cluster. + kind delete cluster --name=$(KIND_CLUSTER_NAME) + docker stop kind-registry && docker rm kind-registry + +.PHONY: tilt-up +tilt-up: $(KUSTOMIZE) $(KUBECTL) kind-create ## start tilt and build kind cluster if needed + EXP_CLUSTER_RESOURCE_SET=true tilt up + +.PHONY: delete-cluster +delete-cluster: delete-workload-cluster ## Deletes the kind cluster "metal" + kind delete cluster --name=$(KIND_CLUSTER_NAME) diff --git a/Tiltfile b/Tiltfile new file mode 100644 index 0000000..e39ed85 --- /dev/null +++ b/Tiltfile @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +#// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +#// SPDX-License-Identifier: Apache-2.0 + +update_settings(k8s_upsert_timeout_secs=60) # on first tilt up, often can take longer than 30 seconds + +settings = { + "allowed_contexts": [ + "kind-metal" + ], + "kubectl": "./bin/kubectl", + "cert_manager_version": "v1.15.3", +} + +if "allowed_contexts" in settings: + allow_k8s_contexts(settings.get("allowed_contexts")) + +def deploy_cert_manager(): + kubectl = settings.get("kubectl") + version = settings.get("cert_manager_version") + print("Installing cert-manager") + local("{} apply -f https://github.com/cert-manager/cert-manager/releases/download/{}/cert-manager.yaml".format(kubectl, version), quiet=True, echo_off=True) + + print("Waiting for cert-manager to start") + local("{} wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager".format(kubectl), quiet=True, echo_off=True) + local("{} wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager-cainjector".format(kubectl), quiet=True, echo_off=True) + local("{} wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager-webhook".format(kubectl), quiet=True, echo_off=True) + +def waitforsystem(): + kubectl = settings.get("kubectl") + print("Waiting for metal-operator to start") + local("{} wait --for=condition=ready --timeout=300s -n metal-operator-system pod --all".format(kubectl), quiet=False, echo_off=True) + +############################## +# Actual work happens here +############################## + +deploy_cert_manager() + +docker_build('controller', '.', target = 'manager') + +yaml = kustomize('./config/dev') + +k8s_yaml(yaml) diff --git a/config/dev/kustomization.yaml b/config/dev/kustomization.yaml index 10972c7..277626a 100644 --- a/config/dev/kustomization.yaml +++ b/config/dev/kustomization.yaml @@ -1,5 +1,13 @@ resources: - ../default +- ../redfish-mockup patches: - path: delete_manager_auth_proxy_patch.yaml +- path: manager_patch.yaml + +secretGenerator: +- name: macdb + namespace: metal-operator-system + files: + - macdb.yaml diff --git a/config/dev/macdb.yaml b/config/dev/macdb.yaml new file mode 100644 index 0000000..3a05a41 --- /dev/null +++ b/config/dev/macdb.yaml @@ -0,0 +1,12 @@ +macPrefixes: +- macPrefix: 23 + manufacturer: Foo + protocol: RedfishLocal + port: 8000 + type: bmc + defaultCredentials: + - username: foo + password: bar + console: + type: ssh + port: 22 diff --git a/config/dev/manager_patch.yaml b/config/dev/manager_patch.yaml new file mode 100644 index 0000000..78d93e1 --- /dev/null +++ b/config/dev/manager_patch.yaml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + - --mac-prefixes-file=/etc/macdb/macdb.yaml + - --probe-image=ghcr.io/ironcore-dev/metalprobe:latest + - --probe-os-image=ghcr.io/ironcore-dev/os-images/gardenlinux:1443 + - --registry-url=http://127.0.0.1:30000 + ports: + - containerPort: 30000 + volumeMounts: + - mountPath: /etc/macdb/ + name: macdb + - name: redfish + image: dmtf/redfish-mockup-server:latest + ports: + - containerPort: 8000 + securityContext: + runAsNonRoot: false + volumes: + - name: macdb + secret: + defaultMode: 420 + secretName: macdb diff --git a/config/redfish-mockup/kustomization.yaml b/config/redfish-mockup/kustomization.yaml new file mode 100644 index 0000000..c23b242 --- /dev/null +++ b/config/redfish-mockup/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- redfish_mockup_endpoint.yaml +- redfish_mockup_service.yaml diff --git a/config/redfish-mockup/redfish_mockup_endpoint.yaml b/config/redfish-mockup/redfish_mockup_endpoint.yaml new file mode 100644 index 0000000..0df99e9 --- /dev/null +++ b/config/redfish-mockup/redfish_mockup_endpoint.yaml @@ -0,0 +1,13 @@ +apiVersion: metal.ironcore.dev/v1alpha1 +kind: Endpoint +metadata: + labels: + app.kubernetes.io/name: endpoint + app.kubernetes.io/instance: endpoint-sample + app.kubernetes.io/part-of: metal-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: metal-operator + name: endpoint-sample +spec: + ip: "127.0.0.1" + macAddress: "23:11:8A:33:CF:EA" diff --git a/config/redfish-mockup/redfish_mockup_service.yaml b/config/redfish-mockup/redfish_mockup_service.yaml new file mode 100644 index 0000000..91129d7 --- /dev/null +++ b/config/redfish-mockup/redfish_mockup_service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: redfish + namespace: metal-operator-system +spec: + ports: + - port: 8000 + targetPort: 8000 + selector: + control-plane: controller-manager diff --git a/scripts/kind-with-registry.sh b/scripts/kind-with-registry.sh new file mode 100755 index 0000000..a312827 --- /dev/null +++ b/scripts/kind-with-registry.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +#// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +#// SPDX-License-Identifier: Apache-2.0 + +set -o errexit +set -o nounset +set -o pipefail + + +REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +KUBECTL=$REPO_ROOT/bin/kubectl + +# desired kind cluster name; default is "metal" +KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-metal}" + +if [[ "$(kind get clusters)" =~ .*"${KIND_CLUSTER_NAME}".* ]]; then + echo "cluster already exists, moving on" + exit 0 +fi + +reg_name='kind-registry' +reg_port="${KIND_REGISTRY_PORT:-5000}" + +# create registry container unless it already exists +running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" +if [ "${running}" != 'true' ]; then + docker run -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" registry:2 +fi + +# create a cluster with the local registry enabled in containerd +cat <