Skip to content
Merged
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
10 changes: 0 additions & 10 deletions .github/ISSUE_TEMPLATE/enhancement_request.md

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2025 Schwarz IT KG

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
SOURCES := Makefile go.mod go.sum $(shell find $(DEST) -name '*.go' 2>/dev/null)
VERSION ?= $(shell git describe --dirty --tags --match='v*' 2>/dev/null || git rev-parse --short HEAD)
REGISTRY ?= reg3.infra.ske.eu01.stackit.cloud
REGISTRY ?= ghcr.io
REPO ?= stackitcloud/machine-controller-manager-provider-stackit
PUSH ?= true
PLATFORMS ?= amd64 arm64
Expand Down Expand Up @@ -78,3 +78,19 @@ mocks: $(MOCKGEN)
.PHONY: generate
generate: mocks
go generate ./...

.PHONY: start
start:
go run \
cmd/machine-controller/main.go \
--control-kubeconfig=$(CONTROL_KUBECONFIG) \
--target-kubeconfig=$(TARGET_KUBECONFIG) \
--namespace=$(CONTROL_NAMESPACE) \
--machine-creation-timeout=20m \
--machine-drain-timeout=5m \
--machine-health-timeout=10m \
--machine-pv-detach-timeout=2m \
--machine-safety-apiserver-statuscheck-timeout=30s \
--machine-safety-apiserver-statuscheck-period=1m \
--machine-safety-orphan-vms-period=30m \
--v=3
2 changes: 2 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners

reviewers:
- machine-controller-manager-provider-stackit-reviewers
approvers:
Expand Down
132 changes: 52 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,64 @@
# machine-controller-manager-provider-stackit

[![GitHub License](https://img.shields.io/github/license/stackitcloud/stackit-sdk-go)](https://www.apache.org/licenses/LICENSE-2.0)
[![GitHub License](https://img.shields.io/github/license/stackitcloud/machine-controller-manager-provider-stackit)](https://www.apache.org/licenses/LICENSE-2.0)

Out of tree (controller based) implementation for `STACKIT` as a provider for Gardener.

A Machine Controller Manager (MCM) external provider implementation for STACKIT cloud infrastructure. This provider enables Gardener to manage virtual machines on STACKIT using the declarative Kubernetes API.
A Machine Controller Manager (MCM) provider implementation for STACKIT cloud infrastructure. This provider enables Gardener to manage virtual machines on STACKIT using the declarative Kubernetes API.

The provider was built following the [MCM provider development guidelines](https://github.com/gardener/machine-controller-manager/blob/master/docs/development/cp_support_new.md) and bootstrapped from the [sample provider template](https://github.com/gardener/machine-controller-manager-provider-sampleprovider).

## Project Structure

```sh
machine-controller-manager-provider-stackit/
├── cmd/
│ └── machine-controller/
│ └── main.go # Provider entrypoint
├── pkg/
│ ├── provider/
│ │ ├── core.go # Core provider implementation
│ │ ├── provider.go # Driver interface implementation
│ │ ├── stackit_client.go # STACKIT client interface
│ │ ├── sdk_client.go # STACKIT SDK wrapper implementation
│ │ ├── helpers.go # SDK type conversion utilities
│ │ ├── apis/
│ │ │ ├── provider_spec.go # ProviderSpec CRD definitions
│ │ │ └── validation/ # Field validation logic
│ │ └── *_test.go # Unit tests
│ └── spi/
│ └── spi.go # Service provider interface
├── test/
│ └── e2e/ # End-to-end integration tests
├── samples/ # Example manifests
├── kubernetes/ # Deployment manifests
└── vendor/ # Go module dependencies
```

## Getting Started

### Deployment
### Examples

See the [samples/](./samples/) directory for example manifests including:

- [`secret.yaml`](./samples/secret.yaml) - STACKIT credentials configuration
- [`machine-class.yaml`](./samples/machine-class.yaml) - MachineClass definition
- [`machine.yaml`](./samples/machine.yaml) - Individual Machine example
- [`machine-deployment.yaml`](./samples/machine-deployment.yaml) - MachineDeployment for scaled workloads
- [`deployment.yaml`](./kubernetes/deployment.yaml) - Provider controller deployment
- [`deployment.yaml`](./samples/deployment.yaml) - Provider controller deployment

### Minimal MachineClass Example

Here's a bare minimum MachineClass configuration:

```yaml
apiVersion: machine.sapcloud.io/v1alpha1
kind: MachineClass
metadata:
name: stackit-machine
namespace: default
providerSpec:
region: eu01
machineType: c2i.2
imageId: "12345678-1234-1234-1234-123456789012"
secretRef:
name: stackit-credentials
namespace: default
```

Deploy using standard kubectl commands:
For detailed information on all available configuration fields, see the [MachineClass documentation](./docs/machine-class.md).

## Local Testing & Development

Local development runs the provider and MCM against a real Gardener shoot on STACKIT (local kind cluster is not suitable). Follow the steps in the [local development guide](./docs/development.md).

Use the Makefile targets for testing:

```sh
kubectl apply -f samples/secret.yaml
kubectl apply -f samples/machine-class.yaml
kubectl apply -f samples/machine.yaml
# Run tests
make test

# Verify code formatting and run all checks
make verify

# Format code
make fmt

# Build container image
make image
```

## STACKIT SDK Integration
Expand All @@ -65,13 +71,11 @@ Each provider instance is bound to a single STACKIT project via the service acco

The provider requires STACKIT credentials to be provided via a Kubernetes Secret. The Secret must contain the following fields:

| Field | Required | Description |
| ------------------- | -------- | ---------------------------------------------------------------- |
| `projectId` | Yes | STACKIT project UUID |
| `serviceAccountKey` | Yes | STACKIT service account credentials (JSON format) |
| `region` | Yes | STACKIT region (e.g., `eu01-1`, `eu01-2`) |
| `userData` | No | Default cloud-init user data (can be overridden in ProviderSpec) |
| `networkId` | No | Default network UUID (can be overridden in ProviderSpec) |
| Field | Required | Description |
| --------------------- | -------- | ---------------------------------------------------------------- |
| `project-id` | Yes | STACKIT project UUID |
| `serviceaccount.json` | Yes | STACKIT service account credentials (JSON format) |
| `userData` | No | Default cloud-init user data (can be overridden in ProviderSpec) |

The service account key should be obtained from the STACKIT Portal (Project Settings → Service Accounts → Create Key) and contains JWT credentials and a private key for secure authentication.

Expand All @@ -81,46 +85,14 @@ The service account key should be obtained from the STACKIT Portal (Project Sett

The provider supports the following environment variables for configuration:

| Variable | Default | Description |
| ---------------------- | ------------- | ------------------------------------------------------------------ |
| `STACKIT_API_ENDPOINT` | (SDK default) | Override STACKIT API endpoint URL (useful for testing) |
| `STACKIT_NO_AUTH` | `false` | Skip authentication (for testing with mock servers, set to `true`) |
| Variable | Default | Description |
| ----------------------- | ------------- | ------------------------------------------------------------------ |
| `STACKIT_IAAS_ENDPOINT` | (SDK default) | Override STACKIT API endpoint URL (useful for testing) |
| `STACKIT_TOKEN_BASEURL` | (SDK default) | Override STACKIT Token endpoint URL (useful for testing) |
| `STACKIT_NO_AUTH` | `false` | Skip authentication (for testing with mock servers, set to `true`) |

**Note:** `STACKIT_NO_AUTH=true` is only intended for testing environments with mock servers. It skips the authenticaiton step and communicates with the STACKIT API without authenticating itself. Do not use in production.

## Configuration Reference

### ProviderSpec Fields

| Field | Type | Required | Description |
| --------------------- | ---------------------- | -------- | ------------------------------------------------ |
| `machineType` | string | Yes | STACKIT server type (e.g., "c2i.2", "m2i.8") |
| `imageId` | string | Yes | UUID of the OS image |
| `labels` | map[string]string | No | Labels for server identification |
| `networking` | NetworkingSpec | No | Network configuration (NetworkID or NICIDs) |
| `securityGroups` | []string | No | Security group names |
| `userData` | string | No | Cloud-init user data (overrides Secret.userData) |
| `bootVolume` | BootVolumeSpec | No | Boot disk configuration |
| `volumes` | []string | No | UUIDs of additional volumes to attach |
| `keypairName` | string | No | SSH keypair name |
| `availabilityZone` | string | No | Availability zone (e.g., "eu01-1") |
| `affinityGroup` | string | No | UUID of affinity group |
| `serviceAccountMails` | []string | No | Service account email addresses (max 1) |
| `agent` | AgentSpec | No | STACKIT agent configuration |
| `metadata` | map[string]interface{} | No | Custom metadata key-value pairs |

### Local Testing

Use the local development environment for rapid iteration:

```sh
# Set up dev environment
just dev

# Or run provider locally for debugging
just start
```

## References

### Machine Controller Manager
Expand All @@ -144,4 +116,4 @@ just start
- [STACKIT Portal](https://portal.stackit.cloud/) - STACKIT management console
- [Service Accounts](https://docs.stackit.cloud/stackit/en/service-accounts-134415819.html) - Creating and managing service accounts
- [Service Account Keys](https://docs.stackit.cloud/stackit/en/usage-of-the-service-account-keys-in-stackit-175112464.html) - API authentication setup
- [IaaS API Documentation](https://docs.stackit.cloud/) - STACKIT IaaS REST API reference
- [IaaS API v2 Documentation](https://docs.api.stackit.cloud/documentation/iaas/version/v2) - STACKIT IaaS REST API reference
7 changes: 0 additions & 7 deletions config/crd/kustomization.yaml

This file was deleted.

127 changes: 0 additions & 127 deletions config/crd/machine.sapcloud.io_machineclasses.yaml

This file was deleted.

Loading