diff --git a/.cruft.json b/.cruft.json index 4b3f767..261853e 100644 --- a/.cruft.json +++ b/.cruft.json @@ -21,9 +21,9 @@ "auto_release": "y", "copyright_holder": "VSHN AG ", "copyright_year": "2026", - "github_owner": "vshn", + "github_owner": "projectsyn", "github_name": "component-capi-provider-cloudscale", - "github_url": "https://github.com/vshn/component-capi-provider-cloudscale", + "github_url": "https://github.com/projectsyn/component-capi-provider-cloudscale", "_template": "https://github.com/projectsyn/commodore-component-template.git", "_commit": "c61b93c6740fb1aaad80e82716a8400d2df31e80" } diff --git a/.gitignore b/.gitignore index f6ff082..1ec97e6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /_public # Additional entries +envsubst-v* diff --git a/.yamllint.yml b/.yamllint.yml index 92aea6c..f109579 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -22,3 +22,4 @@ ignore: | manifests/ vendor/ compiled/ + tests/golden/** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd89a71..318540c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,4 +3,4 @@ This code repository is part of Project Syn and the contribution guide at https://syn.tools/syn/about/contribution_guide.html does apply. -Submit Pull Requests at https://github.com/vshn/component-capi-provider-cloudscale/pulls. +Submit Pull Requests at https://github.com/projectsyn/component-capi-provider-cloudscale/pulls. diff --git a/class/capi-provider-cloudscale.yml b/class/capi-provider-cloudscale.yml index 764155d..ff0e34c 100644 --- a/class/capi-provider-cloudscale.yml +++ b/class/capi-provider-cloudscale.yml @@ -8,4 +8,21 @@ parameters: - input_paths: - ${_base_directory}/component/main.jsonnet input_type: jsonnet - output_path: capi-provider-cloudscale/ + output_path: ${_base_directory}/manifests/capi-provider-cloudscale/ + - input_type: external + output_path: . + input_paths: + - ${_kustomize_wrapper} + env_vars: + INPUT_DIR: ${_base_directory}/manifests/capi-provider-cloudscale/ + args: + - ${_base_directory}/manifests/capi-provider-cloudscale-rendered/ + - input_type: external + output_path: . + input_paths: + - ${_base_directory}/envsubst-dir + # map env vars from parameters as needed + env_vars: ${capi_provider_cloudscale:variables} + args: + - ${_base_directory}/manifests/capi-provider-cloudscale-rendered + - \${compiled_target_dir}/capi-provider-cloudscale/10_kustomize diff --git a/class/defaults.yml b/class/defaults.yml index 2ae8cd2..78acd4a 100644 --- a/class/defaults.yml +++ b/class/defaults.yml @@ -2,4 +2,13 @@ parameters: capi_provider_cloudscale: =_metadata: multi_tenant: true - namespace: syn-capi-provider-cloudscale + namespace: syn-cluster-api + + images: + capi-provider-cloudscale: + registry: quay.io + image: cloudscalech/cluster-api-cloudscale-controller + tag: v1.0.1 + + variables: + CLOUDSCALE_API_TOKEN: ?{vaultkv:${cluster:tenant}/${cluster:name}/cloudscale/token} diff --git a/component/app.jsonnet b/component/app.jsonnet index 0500ff4..6f8205c 100644 --- a/component/app.jsonnet +++ b/component/app.jsonnet @@ -3,7 +3,13 @@ local inv = kap.inventory(); local params = inv.parameters.capi_provider_cloudscale; local argocd = import 'lib/argocd.libjsonnet'; -local app = argocd.App('capi-provider-cloudscale', params.namespace); +local app = argocd.App('capi-provider-cloudscale', params.namespace) { + spec+: { + syncOptions+: [ + 'ServerSideApply=true', + ], + }, +}; local appPath = local project = std.get(std.get(app, 'spec', {}), 'project', 'syn'); diff --git a/component/main.jsonnet b/component/main.jsonnet index d5db840..c40d278 100644 --- a/component/main.jsonnet +++ b/component/main.jsonnet @@ -1,10 +1,45 @@ -// main template for capi-provider-cloudscale +local com = import 'lib/commodore.libjsonnet'; local kap = import 'lib/kapitan.libjsonnet'; local kube = import 'lib/kube.libjsonnet'; local inv = kap.inventory(); // The hiera parameters for the component local params = inv.parameters.capi_provider_cloudscale; -// Define outputs below -{ +assert std.member(inv.applications, 'capi-core') : 'Component capi-provider-cloudscale requires component capi-core'; +assert std.length(params.variables.CLOUDSCALE_API_TOKEN) > 0 : 'capi-provider-cloudscale:variables:CLOUDSCALE_API_TOKEN must be set'; + +local manifest_path = 'config/default'; + +com.Kustomization( + 'https://github.com/cloudscale-ch/cluster-api-provider-cloudscale/' + manifest_path, + params.images['capi-provider-cloudscale'].tag, + { + 'quay.io/cloudscalech/capcs-staging': { + local image = params.images['capi-provider-cloudscale'], + newTag: image.tag, + newName: '%(registry)s/%(image)s' % image, + }, + }, + { + namespace: params.namespace, + labels+: [ + { + pairs: { + 'app.kubernetes.io/managed-by': 'commodore', + }, + }, + ], + patchesStrategicMerge: [ 'rm-namespace.yaml' ], + }, +) { + 'rm-namespace': [ + { + '$patch': 'delete', + apiVersion: 'v1', + kind: 'Namespace', + metadata: { + name: 'capcs-system', + }, + }, + ], } diff --git a/docs/modules/ROOT/pages/references/parameters.adoc b/docs/modules/ROOT/pages/references/parameters.adoc index 3161200..eea7601 100644 --- a/docs/modules/ROOT/pages/references/parameters.adoc +++ b/docs/modules/ROOT/pages/references/parameters.adoc @@ -6,14 +6,49 @@ The parent key for all of the following parameters is `capi_provider_cloudscale` [horizontal] type:: string -default:: `syn-capi-provider-cloudscale` +default:: `syn-cluster-api` The namespace in which to deploy this component. +The component assumes that this namespace already exists via dependency `component-capi-core`. +== `images` + +[horizontal] +type:: dict +default:: See `class/defaults.yml` + +The default Docker image location and tag to use for the CAPI provider cloudscale component (key `capi-provider-cloudscale`). + +Entries in this dict should be dictionaries with keys `registry`, `image`, and `tag`. This structure provides the basis for dependency maintenance with Renovate. + +The value of `capi-provider-cloudscale.tag` in this dict is used by the component to select the version of the upstream CAPI provider cloudscale components. + +== `variables` + +[horizontal] +type:: dict +default:: See `class/defaults.yml` + +An object with environment variables that the generated manifests will be templated with, similar to `clusterctl`. +Variables should be specified in the format: + +[source,yaml] +---- +variables: + CLOUDSCALE_API_TOKEN: +---- + +Note that the `CLOUDSCALE_API_TOKEN` variable is mandatory for this component. +The default is a reference to vault. == Example [source,yaml] ---- namespace: example-namespace +images: + capi-provider-cloudscale: + tag: v1.14.0 +variables: + CLOUDSCALE_API_TOKEN: value ---- diff --git a/envsubst-dir b/envsubst-dir new file mode 100755 index 0000000..8a83f90 --- /dev/null +++ b/envsubst-dir @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +basedir=$(dirname "$0") +version="${ENVSUBST_VERSION:-v1.4.3}" + +src="$1" +dst="$2" + +ensure_envsubst () { + set -eu + + local dir="$1" + # Version with leading `v`. + local version="$2" + + local arch + arch=$(uname -m) + case $arch in + aarch64|arm64) arch="arm64";; + x86_64|amd64) arch="x86_64";; + *) + >&2 echo "Unsupported arch: $arch" + exit 5 + :: + esac + + local os + os=$(uname -s) + if [[ "$os" != "Linux" && "$os" != "Darwin" ]]; then + >&2 echo "Unsupported os: $os" + exit 5 + fi + + if [ ! -x "${dir}/envsubst-${version}-${os}-${arch}" ]; then + download_envsubst "${dir}" "${version}" "${os}" "${arch}" + else + >&2 echo "envsubst-${version}-${os}-${arch} already installed" + fi + + echo "${dir}/envsubst-${version}-${os}-${arch}" +} + +download_envsubst () { + set -eu + + local dir="$1" + local version="$2" + local os="$3" + local arch="$4" + + local url="https://github.com/a8m/envsubst/releases/download/${version}/envsubst-${os}-${arch}" + + >&2 echo "Downloading envsubst-${version}-${os}-${arch} from ${url}" + + curl -fsSLo "${dir}/envsubst-${version}-${os}-${arch}" "${url}" + chmod +x "${dir}/envsubst-${version}-${os}-${arch}" + + >&2 echo "envsubst-${version}-${os}-${arch} successfully installed" +} + +envsubst="$(ensure_envsubst "${basedir}" "${version}")" + +mkdir -p "$dst" + +find "$src" -type f -name '*.yaml' -print0 | +while IFS= read -r -d '' file; do + relative="${file#$src/}" + output="$dst/$relative" + + mkdir -p "$(dirname "$output")" + + "$envsubst" \ + -no-unset \ + -i "$file" \ + -o "$output" +done diff --git a/tests/defaults.yml b/tests/defaults.yml index a4da5b7..51ceae8 100644 --- a/tests/defaults.yml +++ b/tests/defaults.yml @@ -1,3 +1,6 @@ # Overwrite parameters here -# parameters: {...} +applications: + - capi-core + +parameters: {} diff --git a/tests/golden/defaults/capi-provider-cloudscale/apps/capi-provider-cloudscale.yaml b/tests/golden/defaults/capi-provider-cloudscale/apps/capi-provider-cloudscale.yaml index e69de29..1b6582d 100644 --- a/tests/golden/defaults/capi-provider-cloudscale/apps/capi-provider-cloudscale.yaml +++ b/tests/golden/defaults/capi-provider-cloudscale/apps/capi-provider-cloudscale.yaml @@ -0,0 +1,3 @@ +spec: + syncOptions: + - ServerSideApply=true diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_capcs-mutating-webhook-configuration.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_capcs-mutating-webhook-configuration.yaml new file mode 100644 index 0000000..d84a4c6 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_capcs-mutating-webhook-configuration.yaml @@ -0,0 +1,90 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: capcs-system/capcs-serving-cert + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /mutate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalecluster + failurePolicy: Fail + name: mcloudscalecluster-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscaleclusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /mutate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscaleclustertemplate + failurePolicy: Fail + name: mcloudscaleclustertemplate-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscaleclustertemplates + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /mutate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalemachine + failurePolicy: Fail + name: mcloudscalemachine-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscalemachines + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /mutate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalemachinetemplate + failurePolicy: Fail + name: mcloudscalemachinetemplate-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscalemachinetemplates + sideEffects: None diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_capcs-validating-webhook-configuration.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_capcs-validating-webhook-configuration.yaml new file mode 100644 index 0000000..d177e9e --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_capcs-validating-webhook-configuration.yaml @@ -0,0 +1,90 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: capcs-system/capcs-serving-cert + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /validate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalecluster + failurePolicy: Fail + name: vcloudscalecluster-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscaleclusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /validate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscaleclustertemplate + failurePolicy: Fail + name: vcloudscaleclustertemplate-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscaleclustertemplates + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /validate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalemachine + failurePolicy: Fail + name: vcloudscalemachine-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscalemachines + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: capcs-webhook-service + namespace: syn-cluster-api + path: /validate-infrastructure-cluster-x-k8s-io-v1beta2-cloudscalemachinetemplate + failurePolicy: Fail + name: vcloudscalemachinetemplate-v1beta2.kb.io + rules: + - apiGroups: + - infrastructure.cluster.x-k8s.io + apiVersions: + - v1beta2 + operations: + - CREATE + - UPDATE + resources: + - cloudscalemachinetemplates + sideEffects: None diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclusters.infrastructure.cluster.x-k8s.io.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclusters.infrastructure.cluster.x-k8s.io.yaml new file mode 100644 index 0000000..47b3d6c --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclusters.infrastructure.cluster.x-k8s.io.yaml @@ -0,0 +1,413 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + cluster.x-k8s.io/v1beta2: v1beta2 + name: cloudscaleclusters.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: CloudscaleCluster + listKind: CloudscaleClusterList + plural: cloudscaleclusters + singular: cloudscalecluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Cluster + jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name + name: Cluster + type: string + - description: Infrastructure provisioned + jsonPath: .status.initialization.provisioned + name: Provisioned + type: string + - description: cloudscale.ch region + jsonPath: .spec.region + name: Region + type: string + - description: Control plane endpoint + jsonPath: .spec.controlPlaneEndpoint.host + name: Endpoint + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: |- + CloudscaleCluster is the cloudscale.ch infrastructure for a CAPI Cluster. + It owns the networks, control-plane load balancer, optional floating IP, and + server groups that back the cluster's machines. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of CloudscaleCluster + properties: + controlPlaneEndpoint: + description: |- + ControlPlaneEndpoint represents the endpoint to communicate with the control plane. + This is set automatically from the load balancer's VIP address or floating IP. + minProperties: 1 + properties: + host: + description: host is the hostname on which the API server is serving. + maxLength: 512 + minLength: 1 + type: string + port: + description: port is the port on which the API server is serving. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + type: object + controlPlaneLoadBalancer: + description: ControlPlaneLoadBalancer configures the load balancer + for the control plane. + properties: + algorithm: + default: round_robin + description: |- + Algorithm is the cloudscale.ch load-balancing algorithm. + - "round_robin" (default): rotate requests across healthy backends. + - "least_connections": send each request to the backend with the fewest active connections. + - "source_ip": hash the client IP so the same client lands on the same backend. + enum: + - round_robin + - least_connections + - source_ip + type: string + apiServerPort: + default: 6443 + description: |- + APIServerPort is the LB listener port exposed for the Kubernetes API + server. Defaults to 6443. The pool always targets the API server on the + control plane nodes' 6443. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + enabled: + default: true + description: |- + Enabled controls whether a load balancer is created for the control plane. + Set to false for external control planes (e.g., hosted control plane) where the endpoint + is provided externally, or when using a floating IP without a load balancer. + type: boolean + flavor: + default: lb-standard + description: |- + Flavor is the cloudscale.ch load balancer flavor slug. Defaults to + "lb-standard". + type: string + healthMonitor: + description: HealthMonitor configures the load balancer health + monitor. + properties: + delayS: + default: 5 + description: DelayS is the interval between health checks + in seconds. + maximum: 300 + minimum: 1 + type: integer + downThreshold: + default: 3 + description: DownThreshold is the number of failed checks + to mark unhealthy. + maximum: 10 + minimum: 1 + type: integer + timeoutS: + default: 3 + description: TimeoutS is the health check timeout in seconds. + maximum: 300 + minimum: 1 + type: integer + upThreshold: + default: 2 + description: UpThreshold is the number of successful checks + to mark healthy. + maximum: 10 + minimum: 1 + type: integer + type: object + network: + description: |- + Network places the LB VIP on a private network (internal LB). + References spec.networks[].name. Omit for a public LB. + When multiple networks are defined this field is required so the LB + pool members can be registered against a specific subnet. + type: string + type: object + credentialsRef: + description: CredentialsRef references the Secret containing the cloudscale.ch + API token. + properties: + name: + description: Name is the name of the Secret. + type: string + namespace: + description: |- + Namespace is the namespace of the Secret. Defaults to the + CloudscaleCluster's own namespace if unset. + type: string + required: + - name + type: object + floatingIP: + description: |- + FloatingIP configures a floating IP for a stable control plane endpoint. + When the load balancer is enabled (recommended), the floating IP is assigned + to the LB, providing a stable IP that survives LB recreation. + When using a pre-existing floating IP without a load balancer, the user must + configure a dummy interface on the control plane servers (see cloudscale.ch docs) + and ensure the control-plane machine template includes a public interface + ({type: public}), as cloudscale.ch requires a public IPv4 address to assign + a floating IP to a server. + Managed floating IPs require the load balancer to be enabled. + Floating IPs cannot be attached to a load balancer with a private VIP + (i.e. one whose ControlPlaneLoadBalancer.Network is set). + properties: + address: + description: |- + Address references a pre-existing floating IP by its address. + cloudscale.ch identifies floating IPs by their IP address rather than by UUID. + The floating IP is not deleted on cluster teardown. + Mutually exclusive with IPFamily. + type: string + ipFamily: + description: |- + IPFamily creates a new floating IP with this IP version. + A floating IP is a single address, so DualStack is not valid here. + Mutually exclusive with Address. + enum: + - IPv4 + - IPv6 + type: string + type: object + networks: + description: |- + Networks define the private networks for this cluster. + Referenced by name from machine interface specs and LB config. + If empty, defaults to a single managed network named after the cluster. + items: + description: |- + NetworkSpec defines a private network for the cluster. + Exactly one of UUID or CIDR must be specified. + properties: + cidr: + description: |- + CIDR defines the subnet for a controller-managed network. + The network and subnet are created and deleted by CAPCS. + Mutually exclusive with UUID. + type: string + gatewayAddress: + description: |- + GatewayAddress is the gateway IP address for the subnet. + Only applicable when CIDR is set (managed network). + By default, no gateway is configured on the subnet. This ensures + that outbound internet traffic uses the public network interface. + Set this to a specific IP address (e.g., "10.0.0.1") only if you have configured + a NAT gateway or similar infrastructure on the private network. + type: string + name: + description: |- + Name identifies this network within the cluster. + Used to reference this network from machine interface specs and LB config. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ + type: string + uuid: + description: |- + UUID references a pre-existing cloudscale.ch network. + The network is not deleted on cluster teardown. + Mutually exclusive with CIDR. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + region: + description: |- + Region is the cloudscale.ch region the cluster is provisioned in. + Determines the default zone and the set of available flavors. + Immutable after cluster creation. + enum: + - rma + - lpg + type: string + zone: + description: |- + Zone is the cloudscale.ch zone within Region. + Defaults to Region + "1" (e.g., "rma1", "lpg1"). Set explicitly only when + the region offers multiple zones and you need to pin the cluster to one. + Immutable after cluster creation. + type: string + required: + - credentialsRef + - region + type: object + status: + description: status defines the observed state of CloudscaleCluster + properties: + conditions: + description: conditions represent the current state of the CloudscaleCluster + resource. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + floatingIP: + description: FloatingIP is the cloudscale.ch floating IP. + type: string + initialization: + description: Initialization contains v1beta2 initialization tracking. + properties: + provisioned: + description: |- + Provisioned indicates that all cluster infrastructure has been provisioned. + True when Network, Subnet, Load Balancer, and Control Plane Endpoint are ready. + type: boolean + type: object + loadBalancerHealthMonitorID: + description: LoadBalancerHealthMonitorID is the cloudscale.ch load + balancer health monitor UUID. + type: string + loadBalancerID: + description: LoadBalancerID is the cloudscale.ch load balancer UUID. + type: string + loadBalancerListenerID: + description: LoadBalancerListenerID is the cloudscale.ch load balancer + listener UUID for the API server. + type: string + loadBalancerMemberIDs: + description: LoadBalancerMemberIDs are the list of nodes attached + to the loadBalancer. + items: + type: string + type: array + loadBalancerPoolID: + description: LoadBalancerPoolID is the cloudscale.ch load balancer + pool UUID for the API server. + type: string + networks: + description: Networks track the status of each network defined in + spec.networks. + items: + description: NetworkStatus tracks the provisioned state of a single + network. + properties: + cidr: + description: |- + CIDR is the subnet CIDR block. + Set from spec for managed networks or discovered from the API for pre-existing networks. + type: string + managed: + description: |- + Managed indicates whether CAPCS manages this network's lifecycle. + false for pre-existing networks (referenced by UUID), true for CAPCS-created networks (defined by CIDR). + type: boolean + name: + description: Name matches the logical name from spec.networks[].name. + type: string + networkID: + description: NetworkID is the cloudscale.ch network UUID. + type: string + subnetID: + description: SubnetID is the cloudscale.ch subnet UUID. + type: string + required: + - managed + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclustertemplates.infrastructure.cluster.x-k8s.io.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclustertemplates.infrastructure.cluster.x-k8s.io.yaml new file mode 100644 index 0000000..43a7cc0 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscaleclustertemplates.infrastructure.cluster.x-k8s.io.yaml @@ -0,0 +1,315 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + cluster.x-k8s.io/v1beta2: v1beta2 + name: cloudscaleclustertemplates.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: CloudscaleClusterTemplate + listKind: CloudscaleClusterTemplateList + plural: cloudscaleclustertemplates + singular: cloudscaleclustertemplate + scope: Namespaced + versions: + - name: v1beta2 + schema: + openAPIV3Schema: + description: |- + CloudscaleClusterTemplate is a template embedded in a ClusterClass that the + CAPI topology controller uses to materialize a CloudscaleCluster for every + Cluster whose spec.topology.classRef resolves to a ClusterClass referencing + this object. Unlike CloudscaleCluster, this CRD has no controller and no + status — it is consumed only at Cluster creation time by CAPI core. + Its spec is immutable after creation (enforced by the validating webhook); + per-cluster overrides go through ClusterClass variables, not template edits. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of CloudscaleClusterTemplate + properties: + template: + description: |- + Template is the embedded resource the CAPI topology controller stamps out + into a CloudscaleCluster for each Cluster whose ClusterClass references + this CloudscaleClusterTemplate. + properties: + metadata: + description: |- + ObjectMeta supplies labels and annotations that propagate to the + generated CloudscaleCluster. The name/namespace fields are ignored: + the topology controller derives those from the owning Cluster. + minProperties: 1 + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + labels is a map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Spec embeds CloudscaleClusterSpec verbatim and shares the same defaulting + and validation logic via the cluster webhook helpers + (clusterSpecDefault / clusterSpecValidateCreate). + Immutable after creation; override per-cluster fields via + spec.topology.variables on the Cluster instead of mutating this spec. + properties: + controlPlaneEndpoint: + description: |- + ControlPlaneEndpoint represents the endpoint to communicate with the control plane. + This is set automatically from the load balancer's VIP address or floating IP. + minProperties: 1 + properties: + host: + description: host is the hostname on which the API server + is serving. + maxLength: 512 + minLength: 1 + type: string + port: + description: port is the port on which the API server + is serving. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + type: object + controlPlaneLoadBalancer: + description: ControlPlaneLoadBalancer configures the load + balancer for the control plane. + properties: + algorithm: + default: round_robin + description: |- + Algorithm is the cloudscale.ch load-balancing algorithm. + - "round_robin" (default): rotate requests across healthy backends. + - "least_connections": send each request to the backend with the fewest active connections. + - "source_ip": hash the client IP so the same client lands on the same backend. + enum: + - round_robin + - least_connections + - source_ip + type: string + apiServerPort: + default: 6443 + description: |- + APIServerPort is the LB listener port exposed for the Kubernetes API + server. Defaults to 6443. The pool always targets the API server on the + control plane nodes' 6443. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + enabled: + default: true + description: |- + Enabled controls whether a load balancer is created for the control plane. + Set to false for external control planes (e.g., hosted control plane) where the endpoint + is provided externally, or when using a floating IP without a load balancer. + type: boolean + flavor: + default: lb-standard + description: |- + Flavor is the cloudscale.ch load balancer flavor slug. Defaults to + "lb-standard". + type: string + healthMonitor: + description: HealthMonitor configures the load balancer + health monitor. + properties: + delayS: + default: 5 + description: DelayS is the interval between health + checks in seconds. + maximum: 300 + minimum: 1 + type: integer + downThreshold: + default: 3 + description: DownThreshold is the number of failed + checks to mark unhealthy. + maximum: 10 + minimum: 1 + type: integer + timeoutS: + default: 3 + description: TimeoutS is the health check timeout + in seconds. + maximum: 300 + minimum: 1 + type: integer + upThreshold: + default: 2 + description: UpThreshold is the number of successful + checks to mark healthy. + maximum: 10 + minimum: 1 + type: integer + type: object + network: + description: |- + Network places the LB VIP on a private network (internal LB). + References spec.networks[].name. Omit for a public LB. + When multiple networks are defined this field is required so the LB + pool members can be registered against a specific subnet. + type: string + type: object + credentialsRef: + description: CredentialsRef references the Secret containing + the cloudscale.ch API token. + properties: + name: + description: Name is the name of the Secret. + type: string + namespace: + description: |- + Namespace is the namespace of the Secret. Defaults to the + CloudscaleCluster's own namespace if unset. + type: string + required: + - name + type: object + floatingIP: + description: |- + FloatingIP configures a floating IP for a stable control plane endpoint. + When the load balancer is enabled (recommended), the floating IP is assigned + to the LB, providing a stable IP that survives LB recreation. + When using a pre-existing floating IP without a load balancer, the user must + configure a dummy interface on the control plane servers (see cloudscale.ch docs) + and ensure the control-plane machine template includes a public interface + ({type: public}), as cloudscale.ch requires a public IPv4 address to assign + a floating IP to a server. + Managed floating IPs require the load balancer to be enabled. + Floating IPs cannot be attached to a load balancer with a private VIP + (i.e. one whose ControlPlaneLoadBalancer.Network is set). + properties: + address: + description: |- + Address references a pre-existing floating IP by its address. + cloudscale.ch identifies floating IPs by their IP address rather than by UUID. + The floating IP is not deleted on cluster teardown. + Mutually exclusive with IPFamily. + type: string + ipFamily: + description: |- + IPFamily creates a new floating IP with this IP version. + A floating IP is a single address, so DualStack is not valid here. + Mutually exclusive with Address. + enum: + - IPv4 + - IPv6 + type: string + type: object + networks: + description: |- + Networks define the private networks for this cluster. + Referenced by name from machine interface specs and LB config. + If empty, defaults to a single managed network named after the cluster. + items: + description: |- + NetworkSpec defines a private network for the cluster. + Exactly one of UUID or CIDR must be specified. + properties: + cidr: + description: |- + CIDR defines the subnet for a controller-managed network. + The network and subnet are created and deleted by CAPCS. + Mutually exclusive with UUID. + type: string + gatewayAddress: + description: |- + GatewayAddress is the gateway IP address for the subnet. + Only applicable when CIDR is set (managed network). + By default, no gateway is configured on the subnet. This ensures + that outbound internet traffic uses the public network interface. + Set this to a specific IP address (e.g., "10.0.0.1") only if you have configured + a NAT gateway or similar infrastructure on the private network. + type: string + name: + description: |- + Name identifies this network within the cluster. + Used to reference this network from machine interface specs and LB config. + maxLength: 63 + pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ + type: string + uuid: + description: |- + UUID references a pre-existing cloudscale.ch network. + The network is not deleted on cluster teardown. + Mutually exclusive with CIDR. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + region: + description: |- + Region is the cloudscale.ch region the cluster is provisioned in. + Determines the default zone and the set of available flavors. + Immutable after cluster creation. + enum: + - rma + - lpg + type: string + zone: + description: |- + Zone is the cloudscale.ch zone within Region. + Defaults to Region + "1" (e.g., "rma1", "lpg1"). Set explicitly only when + the region offers multiple zones and you need to pin the cluster to one. + Immutable after cluster creation. + type: string + required: + - credentialsRef + - region + type: object + required: + - spec + type: object + required: + - template + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachines.infrastructure.cluster.x-k8s.io.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachines.infrastructure.cluster.x-k8s.io.yaml new file mode 100644 index 0000000..4d8d4da --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachines.infrastructure.cluster.x-k8s.io.yaml @@ -0,0 +1,285 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + cluster.x-k8s.io/v1beta2: v1beta2 + name: cloudscalemachines.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: CloudscaleMachine + listKind: CloudscaleMachineList + plural: cloudscalemachines + singular: cloudscalemachine + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Cluster + jsonPath: .metadata.labels.cluster\.x-k8s\.io/cluster-name + name: Cluster + type: string + - description: Machine provisioned + jsonPath: .status.initialization.provisioned + name: Provisioned + type: string + - description: cloudscale.ch server ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine object + jsonPath: .metadata.ownerReferences[?(@.kind=="Machine")].name + name: Machine + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: |- + CloudscaleMachine represents a single cloudscale.ch server backing a CAPI + Machine. Most spec fields are immutable after creation — to change them, + roll the owning MachineDeployment or KubeadmControlPlane. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of CloudscaleMachine + properties: + flavor: + description: |- + Flavor is the cloudscale.ch server flavor slug, e.g. "flex-4-2" or + "plus-8-4". List available flavors via the cloudscale API + (`GET /v1/flavors`) or the control panel. + Immutable after machine creation. + minLength: 1 + type: string + image: + description: |- + Image identifies the OS image used to boot the server. One of: + - a public image slug (e.g. "ubuntu-24.04"), + - a custom image slug (e.g. "custom:ubuntu-2404-kube-v1.36.0"), or + - a custom image UUID. + For Kubernetes nodes you typically want a custom image built with + image-builder (https://image-builder.sigs.k8s.io/) that already contains + kubelet, containerd, and the chosen Kubernetes version. + minLength: 1 + type: string + interfaces: + description: |- + Interfaces define the network interfaces to attach to the server. + When omitted, the controller defaults to the first cluster network and a public interface + at runtime (cross-resource resolution that the webhook cannot do). + If the cluster uses a floating IP without a load balancer, the control-plane + machine template must explicitly include a public interface ({type: public}). + cloudscale.ch requires a public IPv4 address on the server to assign a floating IP. + items: + description: |- + InterfaceSpec defines a network interface to attach to a server. + Exactly one of Type or Network must be specified. + properties: + ipFamily: + description: |- + IPFamily controls IPv4/IPv6 for a public interface. + Only valid when Type is "public". + Maps to the cloudscale API's per-server use_ipv6 setting: + - IPv4: use_ipv6=false (IPv4 only) + - DualStack: use_ipv6=true (IPv4 + IPv6) + enum: + - IPv4 + - DualStack + type: string + network: + description: |- + Network references a named network from CloudscaleCluster.spec.networks. + Mutually exclusive with Type. + type: string + type: + description: |- + Type is "public" for a public internet interface. + Mutually exclusive with Network. + enum: + - public + type: string + type: object + type: array + x-kubernetes-list-type: atomic + providerID: + description: |- + ProviderID is the unique identifier as specified by the cloud provider. + Format: cloudscale:// + type: string + rootVolumeSize: + description: |- + RootVolumeSize is the root volume size in GB. Minimum 10. If unset, the + cloudscale.ch default for the chosen flavor is used. + minimum: 10 + type: integer + serverGroup: + description: |- + ServerGroup configures anti-affinity placement. + When specified, machines in the same server group are placed on different physical hosts. + N.B.: Only **up to 4 machines** can be placed in the same server group. + properties: + name: + description: |- + Name is the server group name. Machines with the same server group name + in the same zone are placed on different physical hosts. The group is + created automatically the first time CAPCS sees the name. + Immutable after machine creation. + minLength: 1 + type: string + required: + - name + type: object + tags: + additionalProperties: + type: string + description: |- + Tags are user-defined key/value pairs applied to the server as cloudscale + tags. CAPCS additionally sets its own ownership tag with the key + "capcs-cluster-"; do not set keys with the "capcs-" prefix. + type: object + required: + - flavor + - image + type: object + status: + description: status defines the observed state of CloudscaleMachine + properties: + addresses: + description: Addresses contains the machine's addresses. + items: + description: MachineAddress contains information for the node's + address. + properties: + address: + description: address is the machine address. + maxLength: 256 + minLength: 1 + type: string + type: + description: type is the machine address type, one of Hostname, + ExternalIP, InternalIP, ExternalDNS or InternalDNS. + enum: + - Hostname + - ExternalIP + - InternalIP + - ExternalDNS + - InternalDNS + type: string + required: + - address + - type + type: object + type: array + conditions: + description: |- + conditions represent the current state of the CloudscaleMachine resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + initialization: + description: Initialization contains v1beta2 initialization tracking. + properties: + provisioned: + description: |- + Provisioned indicates that the machine infrastructure has been provisioned. + True when the server is running and ready. + type: boolean + type: object + serverGroupID: + description: ServerGroupID is the cloudscale.ch server group UUID. + type: string + serverID: + description: ServerID is the cloudscale.ch server UUID. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachinetemplates.infrastructure.cluster.x-k8s.io.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachinetemplates.infrastructure.cluster.x-k8s.io.yaml new file mode 100644 index 0000000..b33a40b --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apiextensions.k8s.io_v1_customresourcedefinition_cloudscalemachinetemplates.infrastructure.cluster.x-k8s.io.yaml @@ -0,0 +1,251 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + cluster.x-k8s.io/v1beta2: v1beta2 + name: cloudscalemachinetemplates.infrastructure.cluster.x-k8s.io +spec: + group: infrastructure.cluster.x-k8s.io + names: + kind: CloudscaleMachineTemplate + listKind: CloudscaleMachineTemplateList + plural: cloudscalemachinetemplates + singular: cloudscalemachinetemplate + scope: Namespaced + versions: + - name: v1beta2 + schema: + openAPIV3Schema: + description: |- + CloudscaleMachineTemplate is the immutable template a MachineDeployment or + KubeadmControlPlane uses to stamp out CloudscaleMachines. Its Status.Capacity + reports the CPU/memory of the chosen flavor (plus the root volume size) so + the cluster autoscaler can scale a MachineDeployment up from zero replicas. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of CloudscaleMachineTemplate + properties: + template: + description: Template contains the machine template specification. + properties: + spec: + description: Spec is the specification of the desired behavior + of the machine. + properties: + flavor: + description: |- + Flavor is the cloudscale.ch server flavor slug, e.g. "flex-4-2" or + "plus-8-4". List available flavors via the cloudscale API + (`GET /v1/flavors`) or the control panel. + Immutable after machine creation. + minLength: 1 + type: string + image: + description: |- + Image identifies the OS image used to boot the server. One of: + - a public image slug (e.g. "ubuntu-24.04"), + - a custom image slug (e.g. "custom:ubuntu-2404-kube-v1.36.0"), or + - a custom image UUID. + For Kubernetes nodes you typically want a custom image built with + image-builder (https://image-builder.sigs.k8s.io/) that already contains + kubelet, containerd, and the chosen Kubernetes version. + minLength: 1 + type: string + interfaces: + description: |- + Interfaces define the network interfaces to attach to the server. + When omitted, the controller defaults to the first cluster network and a public interface + at runtime (cross-resource resolution that the webhook cannot do). + If the cluster uses a floating IP without a load balancer, the control-plane + machine template must explicitly include a public interface ({type: public}). + cloudscale.ch requires a public IPv4 address on the server to assign a floating IP. + items: + description: |- + InterfaceSpec defines a network interface to attach to a server. + Exactly one of Type or Network must be specified. + properties: + ipFamily: + description: |- + IPFamily controls IPv4/IPv6 for a public interface. + Only valid when Type is "public". + Maps to the cloudscale API's per-server use_ipv6 setting: + - IPv4: use_ipv6=false (IPv4 only) + - DualStack: use_ipv6=true (IPv4 + IPv6) + enum: + - IPv4 + - DualStack + type: string + network: + description: |- + Network references a named network from CloudscaleCluster.spec.networks. + Mutually exclusive with Type. + type: string + type: + description: |- + Type is "public" for a public internet interface. + Mutually exclusive with Network. + enum: + - public + type: string + type: object + type: array + x-kubernetes-list-type: atomic + providerID: + description: |- + ProviderID is the unique identifier as specified by the cloud provider. + Format: cloudscale:// + type: string + rootVolumeSize: + description: |- + RootVolumeSize is the root volume size in GB. Minimum 10. If unset, the + cloudscale.ch default for the chosen flavor is used. + minimum: 10 + type: integer + serverGroup: + description: |- + ServerGroup configures anti-affinity placement. + When specified, machines in the same server group are placed on different physical hosts. + N.B.: Only **up to 4 machines** can be placed in the same server group. + properties: + name: + description: |- + Name is the server group name. Machines with the same server group name + in the same zone are placed on different physical hosts. The group is + created automatically the first time CAPCS sees the name. + Immutable after machine creation. + minLength: 1 + type: string + required: + - name + type: object + tags: + additionalProperties: + type: string + description: |- + Tags are user-defined key/value pairs applied to the server as cloudscale + tags. CAPCS additionally sets its own ownership tag with the key + "capcs-cluster-"; do not set keys with the "capcs-" prefix. + type: object + required: + - flavor + - image + type: object + required: + - spec + type: object + required: + - template + type: object + status: + description: status defines the observed state of CloudscaleMachineTemplate + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Capacity defines the resource capacity for nodes created from this template. + This value is used for autoscaling from zero operations as defined in: + https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md + type: object + conditions: + description: |- + conditions represent the current state of the CloudscaleMachineTemplate resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apps_v1_deployment_capcs-controller-manager.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apps_v1_deployment_capcs-controller-manager.yaml new file mode 100644 index 0000000..dd71fe1 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/apps_v1_deployment_capcs-controller-manager.yaml @@ -0,0 +1,120 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager + name: capcs-controller-manager + namespace: syn-cluster-api +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + - --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + command: + - /manager + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: CLOUDSCALE_API_TOKEN + valueFrom: + secretKeyRef: + key: token + name: capcs-cloudscale + image: quay.io/cloudscalech/cluster-api-cloudscale-controller:v1.0.1 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 15 + periodSeconds: 20 + successThreshold: 1 + timeoutSeconds: 1 + name: manager + ports: + - containerPort: 8081 + name: healthz + protocol: TCP + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: healthz + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: capcs-controller-manager + terminationGracePeriodSeconds: 10 + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/control-plane + - effect: NoSchedule + key: node-role.kubernetes.io/master + volumes: + - name: metrics-certs + secret: + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: metrics-server-cert + - name: webhook-certs + secret: + secretName: webhook-server-cert diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-metrics-certs.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-metrics-certs.yaml new file mode 100644 index 0000000..fec610f --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-metrics-certs.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-metrics-certs + namespace: syn-cluster-api +spec: + dnsNames: + - capcs-controller-manager-metrics-service.capcs-system.svc + - capcs-controller-manager-metrics-service.capcs-system.svc.cluster.local + issuerRef: + kind: Issuer + name: capcs-selfsigned-issuer + secretName: metrics-server-cert diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-serving-cert.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-serving-cert.yaml new file mode 100644 index 0000000..1ee945c --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_certificate_capcs-serving-cert.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-serving-cert + namespace: syn-cluster-api +spec: + dnsNames: + - capcs-webhook-service.capcs-system.svc + - capcs-webhook-service.capcs-system.svc.cluster.local + issuerRef: + kind: Issuer + name: capcs-selfsigned-issuer + secretName: webhook-server-cert diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_issuer_capcs-selfsigned-issuer.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_issuer_capcs-selfsigned-issuer.yaml new file mode 100644 index 0000000..1269c36 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/cert-manager.io_v1_issuer_capcs-selfsigned-issuer.yaml @@ -0,0 +1,11 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-selfsigned-issuer + namespace: syn-cluster-api +spec: + selfSigned: {} diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-manager-role.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-manager-role.yaml new file mode 100644 index 0000000..5a19f1f --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-manager-role.yaml @@ -0,0 +1,70 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-manager-role +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - cluster.x-k8s.io + resources: + - clusters + - clusters/status + verbs: + - get + - list + - watch +- apiGroups: + - cluster.x-k8s.io + resources: + - machines + verbs: + - list + - watch +- apiGroups: + - events.k8s.io + resources: + - events + verbs: + - create + - patch +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - cloudscaleclusters + - cloudscalemachines + - cloudscalemachinetemplates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - cloudscaleclusters/finalizers + - cloudscalemachines/finalizers + verbs: + - update +- apiGroups: + - infrastructure.cluster.x-k8s.io + resources: + - cloudscaleclusters/status + - cloudscalemachines/status + - cloudscalemachinetemplates/status + verbs: + - get + - patch + - update diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-auth-role.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-auth-role.yaml new file mode 100644 index 0000000..f5f6259 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-auth-role.yaml @@ -0,0 +1,20 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-reader.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-reader.yaml new file mode 100644 index 0000000..29825c8 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrole_capcs-metrics-reader.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-manager-rolebinding.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-manager-rolebinding.yaml new file mode 100644 index 0000000..08ff8f6 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-manager-rolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: capcs-manager-role +subjects: +- kind: ServiceAccount + name: capcs-controller-manager + namespace: syn-cluster-api diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-metrics-auth-rolebinding.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-metrics-auth-rolebinding.yaml new file mode 100644 index 0000000..ac03cba --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_clusterrolebinding_capcs-metrics-auth-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: capcs-metrics-auth-role +subjects: +- kind: ServiceAccount + name: capcs-controller-manager + namespace: syn-cluster-api diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_role_capcs-leader-election-role.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_role_capcs-leader-election-role.yaml new file mode 100644 index 0000000..76617ae --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_role_capcs-leader-election-role.yaml @@ -0,0 +1,41 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-leader-election-role + namespace: syn-cluster-api +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_rolebinding_capcs-leader-election-rolebinding.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_rolebinding_capcs-leader-election-rolebinding.yaml new file mode 100644 index 0000000..1a037b8 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/rbac.authorization.k8s.io_v1_rolebinding_capcs-leader-election-rolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-leader-election-rolebinding + namespace: syn-cluster-api +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: capcs-leader-election-role +subjects: +- kind: ServiceAccount + name: capcs-controller-manager + namespace: syn-cluster-api diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_secret_capcs-cloudscale.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_secret_capcs-cloudscale.yaml new file mode 100644 index 0000000..51c2bf6 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_secret_capcs-cloudscale.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/managed-by: commodore + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-cloudscale + namespace: syn-cluster-api +stringData: + token: ?{vaultkv:t-silent-test-1234/c-green-test-1234/cloudscale/token} +type: Opaque diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-controller-manager-metrics-service.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-controller-manager-metrics-service.yaml new file mode 100644 index 0000000..e8cd737 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-controller-manager-metrics-service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager + name: capcs-controller-manager-metrics-service + namespace: syn-cluster-api +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-webhook-service.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-webhook-service.yaml new file mode 100644 index 0000000..6e60254 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_service_capcs-webhook-service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-webhook-service + namespace: syn-cluster-api +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + control-plane: controller-manager diff --git a/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_serviceaccount_capcs-controller-manager.yaml b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_serviceaccount_capcs-controller-manager.yaml new file mode 100644 index 0000000..38173b5 --- /dev/null +++ b/tests/golden/defaults/capi-provider-cloudscale/capi-provider-cloudscale/10_kustomize/v1_serviceaccount_capcs-controller-manager.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: cluster-api-provider-cloudscale + cluster.x-k8s.io/provider: infrastructure-cloudscale-ch-cloudscale + name: capcs-controller-manager + namespace: syn-cluster-api