diff --git a/README.md b/README.md index 3400c72..185bd48 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ task --taskfile https://raw.githubusercontent.com/stuttgart-things/tasks/refs/he ```bash kubectl apply --server-side -k https://github.com/stuttgart-things/helm/cicd/crds/crossplane -# BY TASKFILE +# BY TASKFILE (IS USING GUM+DAGGER) export TASK_X_REMOTE_TASKFILES=1 task --taskfile https://raw.githubusercontent.com/stuttgart-things/tasks/refs/heads/main/kubernetes/helm.yaml helmfile-operation #apply+crossplane ``` @@ -72,61 +72,13 @@ dagger call -m github.com/stuttgart-things/dagger/helm@v0.57.0 \
ADD LOCAL CLUSTER AS KUBERNETES PROVIDER (FILEBASED) ```bash -NAMESPACE="crossplane-system" -KUBECONFIG_DIR="$HOME/.kube" - -# Select kubeconfig file -KUBECONFIG_FILE=$(ls -1 "$KUBECONFIG_DIR" \ - | gum choose --header "Select kubeconfig file") - -KUBECONFIG_PATH="$KUBECONFIG_DIR/$KUBECONFIG_FILE" - -# Secret name -SECRET_NAME=$(gum input \ - --prompt "Secret name: " \ - --value "dev") - -# Create or update secret (idempotent) -kubectl -n "$NAMESPACE" create secret generic "$SECRET_NAME" \ - --from-file=config="$KUBECONFIG_PATH" \ - --dry-run=client -o yaml \ - | kubectl apply -f - -``` - -```bash -NAMESPACE="crossplane-system" - -CONFIG_NAME=$(gum input \ - --prompt "ClusterProviderConfig name: " \ - --value "dev") - -SECRET_NAME=$(kubectl get secret -n "$NAMESPACE" \ - -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \ - | gum choose --header "Select secret") - -SECRET_KEY=$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" \ - -o json \ - | jq -r '.data | keys[]' \ - | gum choose --header "Select key from secret '$SECRET_NAME'") - -if ! gum confirm "Apply ClusterProviderConfig '$CONFIG_NAME' using $SECRET_NAME:$SECRET_KEY?"; then - echo "Aborted." - exit 0 -fi - -kubectl apply -f - < @@ -154,24 +106,13 @@ task --taskfile https://raw.githubusercontent.com/stuttgart-things/crossplane/re ## CONFIGURATIONS -
ANSIBLE-RUN - -* [SEE-HOW-TO-USE](configurations/ansible-run/README.md) - -* INSTALL +
APPLY CROSSPLANE PACKAGES ```bash -cat < ## DEVELOPMENT diff --git a/Taskfile.yaml b/Taskfile.yaml index f2eeb62..847f425 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,6 +8,8 @@ vars: CROSSPLANE_PACKAGE_REGISTRY: ghcr.io DAGGER_CROSSPLANE_MODULE: github.com/stuttgart-things/dagger/crossplane #../dagger/crossplane #github.com/stuttgart-things/dagger/crossplane DAGGER_CROSSPLANE_MODULE_VERSION: v0.59.0 + BLUEPRINT_CROSSPLANE_MODULE: github.com/stuttgart-things/blueprints/crossplane-configuration + BLUEPRINT_CROSSPLANE_MODULE_VERSION: "@v1.40.0" includes: git: @@ -18,124 +20,7 @@ includes: taskfile: https://raw.githubusercontent.com/stuttgart-things/tasks/refs/heads/main/configuration/k2n.yaml tasks: - create-new-configuration: - desc: Interactive wizard-style generation with smart defaults - vars: - BLUEPRINT_CROSSPLANE_MODULE: github.com/stuttgart-things/blueprints/crossplane-configuration - BLUEPRINT_CROSSPLANE_MODULE_VERSION: "@v1.35.0" - cmds: - - | - set -e # Exit on error - - gum style --foreground 212 --bold "🚀 Crossplane Configuration Generator" - echo "" - - # Step 1: Get name (with validation) - while true; do - NAME=$(gum input --placeholder "e.g., storage-platform" --prompt "📝 Name: ") - if [ -n "$NAME" ]; then - break - else - gum style --foreground 9 "Name cannot be empty. Please try again." - fi - done - - # Auto-generate suggested values based on name - GUESSED_KIND=$(echo "$NAME" | awk -F'-' '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1)) tolower(substr($i,2))}}1' OFS='') - GUESSED_SINGULAR=$(echo "$NAME" | sed 's/-//g') - GUESSED_PLURAL="${GUESSED_SINGULAR}s" - GUESSED_CLAIM="${GUESSED_KIND}Claim" - - # Step 2: Get Kind with auto-generated default - KIND=$(gum input --placeholder "e.g., $GUESSED_KIND" --prompt "🏷️ Kind (PascalCase): " --value "$GUESSED_KIND") - - # Step 3: Get XRD Singular with auto-generated default - XRD_SINGULAR=$(gum input --placeholder "e.g., $GUESSED_SINGULAR" --prompt "📦 XRD Singular (lowercase): " --value "$GUESSED_SINGULAR") - - # Step 4: Get XRD Plural with auto-generated default - XRD_PLURAL=$(gum input --placeholder "e.g., $GUESSED_PLURAL" --prompt "📦 XRD Plural (lowercase): " --value "$GUESSED_PLURAL") - - # Auto-generate Claim name - CLAIM_NAME="$GUESSED_CLAIM" - - # Step 5: Select base output location - echo "" - echo "📁 Select base folder for configurations:" - BASE_FOLDER=$(gum file --directory) - if [ -z "$BASE_FOLDER" ]; then - gum style --foreground 9 "No folder selected. Using current directory." - BASE_FOLDER="." - fi - - # Create final output path - OUTPUT_FOLDER="${BASE_FOLDER}/${NAME}" - - # Step 6: Preview - echo "" - gum style --border thick --border-foreground 212 --padding "1 2" --margin "1" \ - "Configuration Preview" \ - "Name: $NAME" \ - "Kind: $KIND" \ - "XRD Singular: $XRD_SINGULAR" \ - "XRD Plural: $XRD_PLURAL" \ - "Claim Name: $CLAIM_NAME" \ - "Base Folder: $BASE_FOLDER" \ - "Output: $OUTPUT_FOLDER" - - # Step 7: Confirm generation - echo "" - if gum confirm "Generate configuration?" --affirmative "Yes" --negative "No"; then - echo "" - echo "🚀 Starting generation..." - - # Create the output folder if it doesn't exist - mkdir -p "$OUTPUT_FOLDER" - - # Check if .configuration-defaults.yaml exists in repo root - DEFAULTS_FILE=".configuration-defaults.yaml" - - if [ -f "$DEFAULTS_FILE" ]; then - DEFAULTS_FLAG="--defaults-file ${DEFAULTS_FILE}" - echo "✓ Using defaults file: $DEFAULTS_FILE" - echo "" - else - gum style --foreground 9 "⚠️ Warning: .configuration-defaults.yaml not found in repo root" - if ! gum confirm "Continue without defaults file?"; then - gum style --foreground 9 "❌ Cancelled" - exit 0 - fi - DEFAULTS_FLAG="" - echo "" - fi - - # Run the generation (show output for debugging) - echo "Running: dagger call -m {{ .BLUEPRINT_CROSSPLANE_MODULE }}{{ .BLUEPRINT_CROSSPLANE_MODULE_VERSION }} \\" - echo " --name \"${NAME}\" \\" - echo " ${DEFAULTS_FLAG} \\" - echo " --variables=\"name=${NAME},kind=${KIND},xrdSingular=${XRD_SINGULAR},xrdPlural=${XRD_PLURAL},claimName=${CLAIM_NAME}\" \\" - echo " export --path=\"${OUTPUT_FOLDER}\"" - echo "" - - if dagger call -m {{ .BLUEPRINT_CROSSPLANE_MODULE }}{{ .BLUEPRINT_CROSSPLANE_MODULE_VERSION }} create \ - --name "${NAME}" \ - ${DEFAULTS_FLAG} \ - --variables="name=${NAME},kind=${KIND},xrdSingular=${XRD_SINGULAR},xrdPlural=${XRD_PLURAL},claimName=${CLAIM_NAME}" \ - export --path="${OUTPUT_FOLDER}"; then - echo "" - gum style --foreground 10 --bold "✅ Successfully generated!" - echo "Output location: $OUTPUT_FOLDER" - else - echo "" - gum style --foreground 9 --bold "❌ Generation failed!" - echo "Check the error messages above for details." - exit 1 - fi - else - echo "" - gum style --foreground 9 "❌ Cancelled" - exit 0 - fi push-configuration-package: desc: Push crossplane configuration package diff --git a/cmds.md b/cmds.md new file mode 100644 index 0000000..f7166c2 --- /dev/null +++ b/cmds.md @@ -0,0 +1,38 @@ +# COMMANDS/TROUBLESHOOTING + +
DEBUG CROSSPLANE PROVIDER + +```bash +# Get provider pods in crossplane-system +kubectl get pods -n crossplane-system + +# Check installed providers +kubectl get providers + +# Find provider service accounts +kubectl get sa -n crossplane-system | grep provider + +# Check provider revision pods +kubectl get pods -n crossplane-system -l pkg.crossplane.io/revision + +# Get all service accounts with their pods +kubectl get pods -n crossplane-system -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.serviceAccountName}{"\n"}{end}' + +### Quick fix: Grant permissions to all service accounts in crossplane-system +kubectl apply -f - < diff --git a/configurations/infra/network-integration/README.md b/configurations/infra/network-integration/README.md new file mode 100644 index 0000000..46352db --- /dev/null +++ b/configurations/infra/network-integration/README.md @@ -0,0 +1,22 @@ +# MyClaim + +This Crossplane Configuration provisions a `NetworkIntegration` Composite Resource Definition (XRD) along with a Composition and an example Claim. + +## DEV + + +```bash +crossplane render examples/claim-kind.yaml \ +compositions/cilium.yaml \ +examples/functions.yaml \ +--include-function-results +``` + + +```bash +crossplane beta trace NetworkIntegration test-cilium +``` + +```bash +kubectl get releases.helm.m.crossplane.io -A +``` diff --git a/configurations/infra/network-integration/apis/definition.yaml b/configurations/infra/network-integration/apis/definition.yaml new file mode 100644 index 0000000..2078141 --- /dev/null +++ b/configurations/infra/network-integration/apis/definition.yaml @@ -0,0 +1,212 @@ +--- +apiVersion: apiextensions.crossplane.io/v2 +kind: CompositeResourceDefinition +metadata: + name: networkintegrations.resources.stuttgart-things.com +spec: + group: resources.stuttgart-things.com + defaultCompositeDeletePolicy: Foreground + scope: Namespaced + names: + kind: NetworkIntegration + plural: networkintegrations + singular: networkintegration + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + description: Platform-level network integration with pluggable CNI stacks + properties: + spec: + type: object + required: + - type + properties: + targetCluster: + type: object + required: + - name + properties: + name: + type: string + description: Name of the ProviderConfig / ClusterProviderConfig + scope: + type: string + enum: + - Namespaced + - Cluster + default: Namespaced + description: | + Whether to use ProviderConfig (Namespaced) + or ClusterProviderConfig (Cluster) + + # ============================================================ + # Network engine selector + # ============================================================ + type: + type: string + enum: + - cilium + description: Selected network integration engine + + # ============================================================ + # Cilium configuration + # ============================================================ + cilium: + type: object + required: + - clusterName + properties: + + # -------------------- + # Cluster identity + # -------------------- + clusterName: + type: string + description: Logical cluster name used for templating + + enableHostServices: + type: boolean + default: true + description: | + Enable host-reachable services. + Required for kind clusters with kube-proxy replacement. + + namespace: + type: string + default: kube-system + + version: + type: string + default: "1.18.5" + description: Cilium Helm chart version + + configProfile: + type: string + enum: [kind, native] + default: kind + description: Values file selector + + # -------------------- + # Core behavior + # -------------------- + kubeProxyReplacement: + type: string + enum: [strict, disabled] + default: strict + + k8sServiceHost: + type: string + description: API server hostname override + + k8sServicePort: + type: integer + default: 6443 + + routingMode: + type: string + enum: [native, tunnel] + default: native + + ipv4NativeRoutingCIDR: + type: string + default: "10.244.0.0/16" + + # -------------------- + # External connectivity + # -------------------- + externalIPs: + type: object + properties: + enabled: + type: boolean + default: true + + ingressController: + type: object + properties: + enabled: + type: boolean + default: false + + # -------------------- + # Client rate limiting + # -------------------- + k8sClientRateLimit: + type: object + properties: + qps: + type: integer + default: 50 + burst: + type: integer + default: 200 + + # -------------------- + # Operator settings + # -------------------- + operator: + type: object + properties: + replicas: + type: integer + default: 2 + rollOutPods: + type: boolean + default: true + + rollOutCiliumPods: + type: boolean + default: true + + # -------------------- + # LoadBalancer & L2 + # -------------------- + loadBalancer: + type: object + properties: + enabled: + type: boolean + default: false + + ipRange: + type: object + required: + - start + - end + properties: + start: + type: string + end: + type: string + + l2Announcements: + type: object + properties: + enabled: + type: boolean + default: true + + devices: + type: array + items: + type: string + default: + - eth0 + - net0 + + # ================================================================ + # Status (for Pipeline composition output) + # ================================================================ + status: + type: object + properties: + installed: + type: boolean + description: Whether the network integration is installed + observedVersion: + type: string + description: Installed Cilium version diff --git a/configurations/infra/network-integration/compositions/cilium.yaml b/configurations/infra/network-integration/compositions/cilium.yaml new file mode 100644 index 0000000..e91f40d --- /dev/null +++ b/configurations/infra/network-integration/compositions/cilium.yaml @@ -0,0 +1,156 @@ +--- +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: networkintegration-cilium + labels: + crossplane.io/xrd: networkintegrations.resources.stuttgart-things.com + resources.stuttgart-things.com/engine: cilium +spec: + compositeTypeRef: + apiVersion: resources.stuttgart-things.com/v1alpha1 + kind: NetworkIntegration + mode: Pipeline + pipeline: + - step: deploy-cilium + functionRef: + name: crossplane-contrib-function-go-templating + input: + apiVersion: gotemplating.fn.crossplane.io/v1beta1 + kind: GoTemplate + source: Inline + inline: + template: | # pragma: allowlist secret + {{- $spec := .observed.composite.resource.spec -}} + {{- $cilium := $spec.cilium -}} + + {{- $scope := $spec.targetCluster.scope | default "Namespaced" -}} + {{- $pcKind := "ProviderConfig" -}} + {{- if eq $scope "Cluster" -}} + {{- $pcKind = "ClusterProviderConfig" -}} + {{- end -}} + + {{- $provider := $spec.targetCluster.name | default "helm-provider-cluster" -}} + --- + apiVersion: helm.m.crossplane.io/v1beta1 + kind: Release + metadata: + annotations: + {{ setResourceNameAnnotation "cilium" }} + labels: + app.kubernetes.io/name: cilium + app.kubernetes.io/managed-by: crossplane + resources.stuttgart-things.com/engine: cilium + spec: + providerConfigRef: + name: {{ $provider }} + kind: {{ $pcKind }} + + forProvider: + namespace: {{ $namespace }} + + chart: + name: cilium + repository: https://helm.cilium.io + version: {{ $cilium.version | default "1.18.5" }} + + values: + kubeProxyReplacement: {{ $cilium.kubeProxyReplacement | default "strict" }} + k8sServiceHost: {{ $cilium.k8sServiceHost | default (printf "%s-control-plane" $clusterName) }} + k8sServicePort: {{ $cilium.k8sServicePort | default 6443 }} + enableHostServices: {{ $cilium.enableHostServices | default true }} + + routingMode: {{ $cilium.routingMode | default "native" }} + ipv4NativeRoutingCIDR: {{ $cilium.ipv4NativeRoutingCIDR | default "10.244.0.0/16" }} + + externalIPs: + enabled: {{ $cilium.externalIPs.enabled | default true }} + + ingressController: + enabled: {{ $cilium.ingressController.enabled | default false }} + + k8sClientRateLimit: + qps: {{ $cilium.k8sClientRateLimit.qps | default 50 }} + burst: {{ $cilium.k8sClientRateLimit.burst | default 200 }} + + rollOutCiliumPods: {{ $cilium.rollOutCiliumPods | default true }} + + operator: + replicas: {{ $cilium.operator.replicas | default 2 }} + rollOutPods: {{ $cilium.operator.rollOutPods | default true }} + + {{- if and $cilium.loadBalancer $cilium.loadBalancer.enabled }} + --- + apiVersion: helm.m.crossplane.io/v1beta1 + kind: Release + metadata: + annotations: + {{ setResourceNameAnnotation "cilium-configuration" }} + labels: + app.kubernetes.io/name: cilium-lb + app.kubernetes.io/managed-by: crossplane + resources.stuttgart-things.com/engine: cilium + spec: + deletionPolicy: Delete + + targetCluster: + name: {{ $provider }} + kind: ClusterProviderConfig + + forProvider: + namespace: {{ $namespace }} + + chart: + name: sthings-cluster + repository: ghcr.io/stuttgart-things + version: 0.3.15 + + values: + kubeProxyReplacement: {{ $cilium.kubeProxyReplacement | default true }} + + l2announcements: + enabled: {{ $cilium.loadBalancer.l2Announcements.enabled | default true }} + + devices: + {{- range $cilium.loadBalancer.devices }} + - {{ . }} + {{- end }} + + customresources: + loadBalancerIPPool: + apiVersion: cilium.io/v2alpha1 + kind: CiliumLoadBalancerIPPool + metadata: + name: ip-pool + spec: + blocks: + - start: "{{ $cilium.loadBalancer.ipRange.start }}" + stop: "{{ $cilium.loadBalancer.ipRange.end }}" + + ciliumL2AnnouncementPolicy: + apiVersion: cilium.io/v2alpha1 + kind: CiliumL2AnnouncementPolicy + metadata: + name: default-l2-announcement-policy + namespace: {{ $namespace }} + spec: + externalIPs: false + loadBalancerIPs: true + interfaces: + - ^eth[0-9]+ + nodeSelector: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + {{- end }} + + --- + apiVersion: resources.stuttgart-things.com/v1alpha1 + kind: NetworkIntegration + status: + installed: true + observedVersion: {{ $cilium.version | default "1.18.5" }} + + - step: automatically-detect-ready-composed-resources + functionRef: + name: crossplane-contrib-function-auto-ready diff --git a/configurations/infra/network-integration/crossplane.yaml b/configurations/infra/network-integration/crossplane.yaml new file mode 100644 index 0000000..023644c --- /dev/null +++ b/configurations/infra/network-integration/crossplane.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: meta.pkg.crossplane.io/v1 +kind: Configuration +metadata: + name: NetworkIntegration + annotations: + meta.crossplane.io/maintainer: patrick.hermann@sva.de + meta.crossplane.io/source: https://github.com/stuttgart-things/crossplane + meta.crossplane.io/license: Apache-2.0 + meta.crossplane.io/description: | + manages lifecycle of NetworkIntegration w/ crossplane + meta.crossplane.io/readme: | + manages lifecycle of NetworkIntegration w/ crossplane +spec: + crossplane: + version: ">=2.13.0" + dependsOn: + - provider: xpkg.upbound.io/crossplane-contrib/provider-helm + version: ">=v0.19.0" diff --git a/configurations/infra/network-integration/examples/claim-kind.yaml b/configurations/infra/network-integration/examples/claim-kind.yaml new file mode 100644 index 0000000..19621f9 --- /dev/null +++ b/configurations/infra/network-integration/examples/claim-kind.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: resources.stuttgart-things.com/v1alpha1 +kind: NetworkIntegration +metadata: + name: test-cilium +spec: + type: cilium + targetCluster: + name: target + cilium: + clusterName: target + version: "1.18.5" diff --git a/configurations/infra/network-integration/examples/functions.yaml b/configurations/infra/network-integration/examples/functions.yaml new file mode 100644 index 0000000..8f4fc8f --- /dev/null +++ b/configurations/infra/network-integration/examples/functions.yaml @@ -0,0 +1,14 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: function-go-templating +spec: + package: xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.11.3 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-auto-ready +spec: + package: xpkg.crossplane.io/crossplane-contrib/function-auto-ready:v0.6.0 +--- diff --git a/configurations/infra/network-integration/examples/provider-config.yaml b/configurations/infra/network-integration/examples/provider-config.yaml new file mode 100644 index 0000000..daad048 --- /dev/null +++ b/configurations/infra/network-integration/examples/provider-config.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: helm.m.crossplane.io/v1beta1 +kind: ProviderConfig +metadata: + name: target +spec: + credentials: + source: Secret + secretRef: + namespace: crossplane-system + name: target + key: config diff --git a/configurations/infra/storage-platform/crossplane.yaml b/configurations/infra/storage-platform/crossplane.yaml index aea3284..0ce860d 100644 --- a/configurations/infra/storage-platform/crossplane.yaml +++ b/configurations/infra/storage-platform/crossplane.yaml @@ -13,12 +13,16 @@ metadata: compositions for OpenEBS and NFS CSI. spec: crossplane: - version: ">=2.13.0" + version: ">=v2.1.3" dependsOn: - provider: xpkg.upbound.io/crossplane-contrib/provider-helm - version: ">=v0.19.0" + version: ">=v1.0.6" - provider: xpkg.upbound.io/crossplane-contrib/provider-kubernetes - version: ">=v0.18.0" + version: ">=v1.2.0" + # Required for Pipeline compositions + - function: xpkg.crossplane.io/crossplane-contrib/function-go-templating + version: ">=v0.11.3" + package: # APIs (XRDs) apis: diff --git a/configurations/infra/storage-platform/examples/openebs.yaml b/configurations/infra/storage-platform/examples/openebs.yaml index befa6a1..ac149b1 100644 --- a/configurations/infra/storage-platform/examples/openebs.yaml +++ b/configurations/infra/storage-platform/examples/openebs.yaml @@ -7,7 +7,7 @@ spec: engine: type: openebs providerConfigRef: - name: helm-provider-prod + name: in-cluster namespace: openebs-system version: 4.2.0 openebs: diff --git a/configurations/k8s/cloud-config/README.md b/configurations/k8s/cloud-config/README.md index d7bd77a..14915fa 100644 --- a/configurations/k8s/cloud-config/README.md +++ b/configurations/k8s/cloud-config/README.md @@ -1,7 +1,84 @@ -# CLOUD CONFIG +# Cloud Config - Crossplane Composition -## DEV +A Crossplane composition that automates the creation of cloud-init configurations for virtual machines. This configuration transforms a `CloudInit` custom resource into Kubernetes secrets containing properly formatted cloud-init userdata. + +## Overview + +This composition provides a declarative way to define VM cloud configurations using Crossplane. It leverages the `function-go-templating` function to render cloud-init YAML from structured XRD specifications. + +## Features + +- **User Management**: Define users, SSH keys, groups, and sudo privileges +- **Package Management**: Specify packages to install and manage updates/upgrades +- **File Management**: Write custom files with specific permissions and ownership +- **Network Configuration**: Optional network configuration support +- **Boot Commands**: Execute commands during boot or runtime +- **SSH Configuration**: Flexible SSH password authentication and root access control + +## Usage + +### Create a CloudInit Resource + +```yaml +apiVersion: resources.stuttgart-things.com/v1alpha1 +kind: CloudInit +metadata: + name: dev2-vm + namespace: default +spec: + providerConfigRef: in-cluster + vmName: dev2 + namespace: default + hostname: dev2 + domain: example.com + timezone: UTC + users: + - name: ubuntu + sshAuthorizedKeys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB... + sudo: "ALL=(ALL) NOPASSWD:ALL" + groups: sudo,docker + shell: /bin/bash + lockPasswd: true + packages: + - curl + - wget + - git + runcmd: + - systemctl enable docker + packageUpdate: true +``` + +The composition will automatically create a Kubernetes Secret containing the rendered cloud-init userdata. + +## Development + +### Render the Composition + +Test the template rendering without applying to the cluster: ```bash crossplane render examples/claim.yaml apis/composition.yaml examples/functions.yaml --include-function-results ``` + +### Trace Resource Status + +Monitor the composition status and track created resources: + +```bash +crossplane beta trace cloudinit.resources.stuttgart-things.com dev2-vm +``` + +### View Resource Tree + +Display the hierarchical relationship of created resources: + +```bash +kubectl tree CloudInit dev2-vm +``` + +## Files + +- `apis/composition.yaml` - Crossplane Composition definition +- `examples/claim.yaml` - Example CloudInit resource +- `examples/functions.yaml` - Function definitions (if applicable) diff --git a/configurations/k8s/cloud-config/crossplane.yaml b/configurations/k8s/cloud-config/crossplane.yaml index e3b2731..221b5e2 100644 --- a/configurations/k8s/cloud-config/crossplane.yaml +++ b/configurations/k8s/cloud-config/crossplane.yaml @@ -15,5 +15,12 @@ spec: crossplane: version: ">=v2.1.3" dependsOn: + # - provider: xpkg.upbound.io/crossplane-contrib/provider-helm + # version: ">=v1.0.6" - provider: xpkg.upbound.io/crossplane-contrib/provider-kubernetes version: ">=v1.2.0" + # Required for Pipeline compositions + - function: xpkg.crossplane.io/crossplane-contrib/function-go-templating + version: ">=v0.11.3" + - function: xpkg.crossplane.io/crossplane-contrib/function-auto-ready + version: ">=v0.6.0" diff --git a/configurations/k8s/cloud-config/examples/claim.yaml b/configurations/k8s/cloud-config/examples/claim.yaml index 881858f..e2482f3 100644 --- a/configurations/k8s/cloud-config/examples/claim.yaml +++ b/configurations/k8s/cloud-config/examples/claim.yaml @@ -5,7 +5,7 @@ metadata: name: dev2-vm namespace: default spec: - providerConfigRef: dev + providerConfigRef: in-cluster vmName: dev2 namespace: default hostname: dev2 diff --git a/configurations/k8s/cloud-config/examples/configuration.yaml b/configurations/k8s/cloud-config/examples/configuration.yaml index 60c33e6..015824c 100644 --- a/configurations/k8s/cloud-config/examples/configuration.yaml +++ b/configurations/k8s/cloud-config/examples/configuration.yaml @@ -4,4 +4,4 @@ kind: Configuration metadata: name: cloud-config spec: - package: ghcr.io/stuttgart-things/crossplane/cloud-config:v0.3.0 + package: ghcr.io/stuttgart-things/crossplane/cloud-config:v0.5.0 diff --git a/configurations/k8s/volume-claim/README.md b/configurations/k8s/volume-claim/README.md index de3e634..6c9b4ec 100644 --- a/configurations/k8s/volume-claim/README.md +++ b/configurations/k8s/volume-claim/README.md @@ -1,14 +1,88 @@ -# VOLUME CLAIM +# Volume Claim - Crossplane Configuration -## DEV +A DRY (Don't Repeat Yourself) Crossplane configuration for managing PersistentVolumeClaims across any storage backend. + +## Overview + +This configuration provides a universal PersistentVolumeClaim abstraction that works seamlessly with any Kubernetes storage provider including Harvester, Longhorn, Rook-Ceph, and standard storage classes. + +## Features + +- **Universal Storage Support**: Works with Harvester, Longhorn, Rook-Ceph, and any Kubernetes storage provider +- **Custom Annotations**: Support for storage-specific annotations (e.g., `harvesterhci.io/imageId`) +- **Flexible Configuration**: Optional labels, selectors, volume modes, and data sources for advanced use cases +- **Simple Interface**: Clean API that abstracts the complexity of PVC management + +## Usage + +### Simple Example + +```yaml +apiVersion: resources.stuttgart-things.com/v1alpha1 +kind: VolumeClaim +metadata: + name: simple-storage + namespace: default +spec: + providerConfigRef: in-cluster + pvcName: app-data + namespace: default + storageClassName: standard + storage: "1Gi" +``` + +### Harvester VM Disk Example + +```yaml +apiVersion: resources.stuttgart-things.com/v1alpha1 +kind: VolumeClaim +metadata: + name: ubuntu-vm-disk +spec: + providerConfigRef: kubernetes-provider + pvcName: ubuntu-vm-root + namespace: vms + storageClassName: longhorn-ubuntu-22.04 + storage: "100Gi" + volumeMode: Block + annotations: + harvesterhci.io/imageId: "harvester-public/ubuntu-22.04" + description: "Ubuntu 22.04 VM root disk" + labels: + app: web-server + environment: production +``` + +## Development + +### Render the Composition + +Test the template rendering without applying to the cluster: ```bash crossplane render examples/claim.yaml \ -apis/composition.yaml \ -examples/functions.yaml \ ---include-function-results + apis/composition.yaml \ + examples/functions.yaml \ + --include-function-results ``` +### Trace Resource Status + +Monitor the composition status and track created resources: + ```bash crossplane beta trace volumeclaim simple-storage ``` + +## Files + +- `apis/composition.yaml` - Crossplane Composition definition +- `examples/claim.yaml` - Example VolumeClaim resource +- `examples/functions.yaml` - Function definitions (if applicable) + +## Requirements + +- Crossplane >= v1.14.1 +- Provider Kubernetes >= v1.2.0 +- Function Go Templating >= v0.11.3 +- Function Auto Ready >= v0.6.0 diff --git a/configurations/k8s/volume-claim/crossplane.yaml b/configurations/k8s/volume-claim/crossplane.yaml index 7e88e66..d402493 100644 --- a/configurations/k8s/volume-claim/crossplane.yaml +++ b/configurations/k8s/volume-claim/crossplane.yaml @@ -71,8 +71,9 @@ spec: dependsOn: - provider: xpkg.upbound.io/crossplane-contrib/provider-kubernetes - version: ">=v0.14.0" - - provider: xpkg.crossplane.io/crossplane-contrib/function-auto-ready - version: ">=v0.2.0" - - provider: xpkg.crossplane.io/crossplane-contrib/function-go-templating - version: ">=v0.5.0" + version: ">=v1.2.0" + # Required for Pipeline compositions + - function: xpkg.crossplane.io/crossplane-contrib/function-go-templating + version: ">=v0.11.3" + - function: xpkg.crossplane.io/crossplane-contrib/function-auto-ready + version: ">=v0.6.0" diff --git a/configurations/k8s/volume-claim/examples/claim.yaml b/configurations/k8s/volume-claim/examples/claim.yaml index 7f42e3a..3c839dd 100644 --- a/configurations/k8s/volume-claim/examples/claim.yaml +++ b/configurations/k8s/volume-claim/examples/claim.yaml @@ -5,7 +5,7 @@ metadata: name: simple-storage namespace: default spec: - providerConfigRef: dev + providerConfigRef: in-cluster annotations: description: "A simple persistent volume claim for application data" pvcName: app-data diff --git a/configurations/k8s/volume-claim/examples/configuration.yaml b/configurations/k8s/volume-claim/examples/configuration.yaml index bf6274d..6ad9142 100644 --- a/configurations/k8s/volume-claim/examples/configuration.yaml +++ b/configurations/k8s/volume-claim/examples/configuration.yaml @@ -4,4 +4,4 @@ kind: Configuration metadata: name: volume-claim spec: - package: ghcr.io/stuttgart-things/crossplane/volume-claim:v0.1.0 + package: ghcr.io/stuttgart-things/crossplane/volume-claim:v0.1.1 diff --git a/dev/ansible-run/apis/composition.yaml b/dev/ansible-run/apis/composition.yaml index 4e770c6..45bea01 100644 --- a/dev/ansible-run/apis/composition.yaml +++ b/dev/ansible-run/apis/composition.yaml @@ -20,7 +20,7 @@ spec: metadata: name: ansiblerun spec: - source: oci://ghcr.io/stuttgart-things/kcl-tekton-pr:0.4.1 + source: oci://ghcr.io/stuttgart-things/kcl-tekton-pr:0.4.6 - step: automatically-detect-ready-composed-resources functionRef: name: crossplane-contrib-function-auto-ready diff --git a/dev/ansible-run/examples/claim-minimal.yaml b/dev/ansible-run/examples/claim-minimal.yaml index a4e3493..68daec1 100644 --- a/dev/ansible-run/examples/claim-minimal.yaml +++ b/dev/ansible-run/examples/claim-minimal.yaml @@ -2,19 +2,19 @@ apiVersion: resources.stuttgart-things.com/v1alpha1 kind: AnsibleRun metadata: - name: run-ansible-test1 + name: run-ansible-baseos namespace: default spec: # CROSSPLANE CONFIGURATION wrapInCrossplane: true - crossplaneObjectName: run-ansible-test-xplane + crossplaneObjectName: run-ansible-baseos crossplaneNamespace: default crossplaneProviderConfig: dev # PIPELINRUN CONFIGURATION - pipelineRunName: run-ansible-xplane + pipelineRunName: run-ansible-baseos namespace: tekton-ci # ANSIBLE CONFIGURATION - ansibleCredentialsSecretName: ansible-credentials + ansibleCredentialsSecretName: ansible-credentials # pragma: allowlist secret ansiblePlaybooks: - sthings.baseos.setup ansibleVarsFile: @@ -23,4 +23,4 @@ spec: - ansible_become+-true - ansible_become_method+-sudo ansibleVarsInventory: - - all+["10.31.102.107"] + - all+["10.100.136.150"] diff --git a/dev/pipeline-integration/README.md b/dev/pipeline-integration/README.md new file mode 100644 index 0000000..3d503ca --- /dev/null +++ b/dev/pipeline-integration/README.md @@ -0,0 +1,16 @@ +# MyClaim + +This Crossplane Configuration provisions a `PipelineIntegration` Composite Resource Definition (XRD) along with a Composition and an example Claim. + +## DEV + +```bash +crossplane render examples/tekton-pipelines.yaml \ +compositions/tekton-pipelines.yaml \ +examples/functions.yaml \ +--include-function-results +``` + +kubectl get clusterproviderconfig.helm.m.crossplane.io -A +kubectl get providerconfig.helm.m.crossplane.io -A +kubectl get release.helm.m.crossplane.io diff --git a/dev/pipeline-integration/apis/definition.yaml b/dev/pipeline-integration/apis/definition.yaml new file mode 100644 index 0000000..ed3f7ae --- /dev/null +++ b/dev/pipeline-integration/apis/definition.yaml @@ -0,0 +1,289 @@ +--- +apiVersion: apiextensions.crossplane.io/v2 +kind: CompositeResourceDefinition +metadata: + name: pipelineintegrations.resources.stuttgart-things.com +spec: + group: resources.stuttgart-things.com + defaultCompositeDeletePolicy: Foreground + scope: Namespaced + names: + kind: PipelineIntegration + plural: pipelineintegrations + singular: pipelineintegration + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + description: Platform-level pipeline offering with pluggable pipeline engines + properties: + spec: + type: object + required: + - engine + properties: + engine: + type: object + required: + - type + properties: + type: + type: string + enum: + - tekton + - argo-workflows + - jenkins + description: Selected pipeline engine + targetCluster: + type: object + required: + - name + properties: + name: + type: string + description: Name of the ProviderConfig / ClusterProviderConfig + scope: + type: string + enum: + - Namespaced + - Cluster + default: Namespaced + description: | + Whether to use ProviderConfig (Namespaced) + or ClusterProviderConfig (Cluster) + # -------------------- + # Tekton configuration + # -------------------- + tekton: + type: object + properties: + namespace: + type: string + default: tekton-operator + description: Namespace for Tekton operator + + pipelineNamespace: + type: string + default: tekton-pipelines + description: Default namespace for Tekton pipelines + + version: + type: string + default: "0.77.5" + description: Tekton chart version + + autoInstallComponents: + type: boolean + default: false + description: Automatically install Tekton components + + imagePullPolicy: + type: string + enum: [Always, IfNotPresent, Never] + default: Always + description: Image pull policy for Tekton components + + disableInlineSpec: + type: string + default: "" + description: Disable inline spec in Tekton + + enableTektonPipeline: + type: boolean + default: true + description: Enable Tekton Pipeline component + + enableTektonTriggers: + type: boolean + default: false + description: Enable Tekton Triggers component + + enableTektonDashboard: + type: boolean + default: false + description: Enable Tekton Dashboard component + + enableTektonPruner: + type: boolean + default: false + description: Enable automatic pruning of old pipeline runs + + chartRepository: + type: string + default: "oci://ghcr.io/stuttgart-things/tekton" + description: OCI Helm chart repository + + # -------------------- + # Argo Workflows configuration + # -------------------- + # argo: + # type: object + # properties: + # namespace: + # type: string + # default: argo-workflows + # description: Namespace for Argo Workflows + + # version: + # type: string + # default: "0.44.0" + # description: Argo Workflows chart version + + # server: + # type: object + # properties: + # enabled: + # type: boolean + # default: true + # description: Enable Argo Workflows server + + # serviceType: + # type: string + # enum: [ClusterIP, NodePort, LoadBalancer] + # default: ClusterIP + + # controller: + # type: object + # properties: + # workflowNamespaces: + # type: array + # items: + # type: string + # description: Namespaces where workflows can run + + # persistence: + # type: object + # properties: + # archive: + # type: boolean + # default: false + # description: Enable workflow archiving + + # artifactRepository: + # type: object + # properties: + # enabled: + # type: boolean + # default: false + # description: Enable artifact repository + + # type: + # type: string + # enum: [s3, gcs, minio] + # default: s3 + + status: + type: object + properties: + installed: + type: boolean + observedVersion: + type: string + endpoint: + type: string + + # -------------------- + # CEL VALIDATIONS + # -------------------- + x-kubernetes-validations: + # targetCluster.scope must be valid + - rule: | + !has(self.spec.targetCluster.scope) + || self.spec.targetCluster.scope in ['Namespaced', 'Cluster'] + message: "targetCluster.scope must be one of: Namespaced, Cluster" + + # name is always required + - rule: | + has(self.spec.targetCluster.name) && self.spec.targetCluster.name != '' + message: "spec.targetCluster.name must be set" + + # ------------------------------------------------------------------ + # Engine-specific configuration requirements + # ------------------------------------------------------------------ + + # Tekton requires spec.tekton to be defined + - rule: "self.spec.engine.type != 'tekton' || has(self.spec.tekton)" + message: "spec.tekton must be defined when engine.type is 'tekton'" + + # (Future-proof) Argo requires spec.argo when enabled + # - rule: "self.spec.engine.type != 'argo-workflows' || has(self.spec.argo)" + # message: "spec.argo must be defined when engine.type is 'argo-workflows'" + + # ------------------------------------------------------------------ + # Target cluster validation + # ------------------------------------------------------------------ + + # Target cluster reference must exist + - rule: "has(self.spec.targetCluster)" + message: "spec.targetCluster must be defined" + + # Target cluster name must be set + - rule: "has(self.spec.targetCluster.name) && self.spec.targetCluster.name != ''" + message: "spec.targetCluster.name must be set and non-empty" + + # ------------------------------------------------------------------ + # Tekton Pipeline component rules + # ------------------------------------------------------------------ + + # Tekton Pipelines enabled → pipelineNamespace must be set + - rule: | + self.spec.engine.type != 'tekton' + || !self.spec.tekton.enableTektonPipeline + || has(self.spec.tekton.pipelineNamespace) + message: "tekton.pipelineNamespace must be set when Tekton Pipeline is enabled" + + # ------------------------------------------------------------------ + # Tekton Triggers rules + # ------------------------------------------------------------------ + + # Triggers require Tekton Pipelines + - rule: | + self.spec.engine.type != 'tekton' + || !self.spec.tekton.enableTektonTriggers + || self.spec.tekton.enableTektonPipeline + message: "Tekton Triggers require enableTektonPipeline=true" + + # ------------------------------------------------------------------ + # Tekton Dashboard rules + # ------------------------------------------------------------------ + + # Dashboard requires Tekton Pipelines + - rule: | + self.spec.engine.type != 'tekton' + || !self.spec.tekton.enableTektonDashboard + || self.spec.tekton.enableTektonPipeline + message: "Tekton Dashboard requires enableTektonPipeline=true" + + # ------------------------------------------------------------------ + # Tekton Pruner rules + # ------------------------------------------------------------------ + + # Pruner requires Tekton Pipelines + - rule: | + self.spec.engine.type != 'tekton' + || !self.spec.tekton.enableTektonPruner + || self.spec.tekton.enableTektonPipeline + message: "Tekton Pruner requires enableTektonPipeline=true" + + # ------------------------------------------------------------------ + # Tekton version validation + # ------------------------------------------------------------------ + + # Version must be non-empty when Tekton is used + - rule: | + self.spec.engine.type != 'tekton' + || (has(self.spec.tekton.version) && self.spec.tekton.version != '') + message: "tekton.version must be set when engine.type is 'tekton'" + + # ------------------------------------------------------------------ + # Image pull policy validation (defensive, even with enum) + # ------------------------------------------------------------------ + + - rule: | + self.spec.engine.type != 'tekton' + || !has(self.spec.tekton.imagePullPolicy) + || self.spec.tekton.imagePullPolicy in ['Always', 'IfNotPresent', 'Never'] + message: "tekton.imagePullPolicy must be one of: Always, IfNotPresent, Never" diff --git a/dev/pipeline-integration/compositions/tekton-pipelines.yaml b/dev/pipeline-integration/compositions/tekton-pipelines.yaml new file mode 100644 index 0000000..2286e8c --- /dev/null +++ b/dev/pipeline-integration/compositions/tekton-pipelines.yaml @@ -0,0 +1,94 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: pipelineintegration-tekton + labels: + crossplane.io/xrd: pipelineintegrations.resources.stuttgart-things.com + resources.stuttgart-things.com/engine: tekton +spec: + compositeTypeRef: + apiVersion: resources.stuttgart-things.com/v1alpha1 + kind: PipelineIntegration + mode: Pipeline + pipeline: + - step: deploy-tekton + functionRef: + name: crossplane-contrib-function-go-templating + input: + apiVersion: gotemplating.fn.crossplane.io/v1beta1 + kind: GoTemplate + source: Inline + inline: + template: | + {{- $spec := .observed.composite.resource.spec -}} + {{- $tekton := $spec.tekton -}} + + {{- $scope := $spec.targetCluster.scope | default "Namespaced" -}} + {{- $pcKind := "ProviderConfig" -}} + {{- if eq $scope "Cluster" -}} + {{- $pcKind = "ClusterProviderConfig" -}} + {{- end -}} + + {{- if $tekton.pipelineNamespace }} + --- + apiVersion: kubernetes.m.crossplane.io/v1alpha1 + kind: Object + metadata: + annotations: + {{ setResourceNameAnnotation "tekton-pipeline-namespace" }} + spec: + providerConfigRef: + name: {{ $spec.targetCluster.name }} + kind: {{ $pcKind }} + forProvider: + manifest: + apiVersion: v1 + kind: Namespace + metadata: + name: {{ $tekton.pipelineNamespace }} + {{- end }} + + --- + apiVersion: helm.m.crossplane.io/v1beta1 + kind: Release + metadata: + annotations: + {{ setResourceNameAnnotation "tekton-operator" }} + spec: + providerConfigRef: + name: {{ $spec.targetCluster.name }} + kind: {{ $pcKind }} + forProvider: + namespace: {{ $tekton.namespace | default "tekton-operator" }} + chart: + name: tekton + repository: {{ $tekton.chartRepository | default "oci://ghcr.io/stuttgart-things/tekton" }} + version: {{ $tekton.version | default "0.77.5" }} + values: + autoInstallComponents: {{ $tekton.autoInstallComponents | default false }} + defaultNamespace: {{ $tekton.pipelineNamespace | default "tekton-pipelines" }} + imagePullPolicy: {{ $tekton.imagePullPolicy | default "Always" }} + disableInlineSpec: "{{ $tekton.disableInlineSpec | default "" }}" + enableTektonPipeline: {{ $tekton.enableTektonPipeline | default true }} + + {{- if $tekton.enableTektonTriggers }} + enableTektonTriggers: true + {{- end }} + + {{- if $tekton.enableTektonDashboard }} + enableTektonDashboard: true + {{- end }} + + tektonPruner: + enabled: {{ $tekton.enableTektonPruner | default false }} + + --- + apiVersion: resources.stuttgart-things.com/v1alpha1 + kind: PipelineIntegration + status: + installed: true + observedVersion: {{ $tekton.version | default "0.77.5" }} + + - step: automatically-detect-ready-composed-resources + functionRef: + name: crossplane-contrib-function-auto-ready diff --git a/dev/pipeline-integration/crossplane.yaml b/dev/pipeline-integration/crossplane.yaml new file mode 100644 index 0000000..ea98ea8 --- /dev/null +++ b/dev/pipeline-integration/crossplane.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: meta.pkg.crossplane.io/v1 +kind: Configuration +metadata: + name: PipelineIntegration + annotations: + meta.crossplane.io/maintainer: patrick.hermann@sva.de + meta.crossplane.io/source: https://github.com/stuttgart-things/crossplane + meta.crossplane.io/license: Apache-2.0 + meta.crossplane.io/description: | + manages lifecycle of PipelineIntegration w/ crossplane + meta.crossplane.io/readme: | + manages lifecycle of PipelineIntegration w/ crossplane +spec: + crossplane: + version: ">=2.13.0" + dependsOn: + - provider: xpkg.upbound.io/crossplane-contrib/provider-helm + version: ">=v0.19.0" diff --git a/dev/pipeline-integration/examples/cluster-provider-config.yaml b/dev/pipeline-integration/examples/cluster-provider-config.yaml new file mode 100644 index 0000000..8469d23 --- /dev/null +++ b/dev/pipeline-integration/examples/cluster-provider-config.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: helm.m.crossplane.io/v1beta1 +kind: ClusterProviderConfig +metadata: + name: target +spec: + credentials: + secretRef: + key: config + name: target + namespace: crossplane-system + source: Secret diff --git a/dev/pipeline-integration/examples/functions.yaml b/dev/pipeline-integration/examples/functions.yaml new file mode 100644 index 0000000..06206be --- /dev/null +++ b/dev/pipeline-integration/examples/functions.yaml @@ -0,0 +1,14 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-go-templating +spec: + package: xpkg.crossplane.io/crossplane-contrib/function-go-templating:v0.11.3 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-auto-ready +spec: + package: xpkg.crossplane.io/crossplane-contrib/function-auto-ready:v0.6.0 +--- diff --git a/dev/pipeline-integration/examples/provider-config.yaml b/dev/pipeline-integration/examples/provider-config.yaml new file mode 100644 index 0000000..589d809 --- /dev/null +++ b/dev/pipeline-integration/examples/provider-config.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: helm.m.crossplane.io/v1beta1 +kind: ProviderConfig +metadata: + name: target + namespace: default +spec: + credentials: + secretRef: + key: config + name: target + namespace: crossplane-system + source: Secret diff --git a/dev/pipeline-integration/examples/tekton-pipelines.yaml b/dev/pipeline-integration/examples/tekton-pipelines.yaml new file mode 100644 index 0000000..3757ccc --- /dev/null +++ b/dev/pipeline-integration/examples/tekton-pipelines.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: resources.stuttgart-things.com/v1alpha1 +kind: PipelineIntegration +metadata: + name: tekton-pipelines + namespace: default +spec: + # CROSSPLANE + targetCluster: + name: target + scope: Cluster # or omit → defaults to Namespaced + + # TECHNOLOGY SELECTION + engine: + type: tekton + # TEKTON-PIPELINES CONFIGURATION + tekton: + namespace: tekton-operator + pipelineNamespace: tekton-pipelines + version: "0.77.5" + autoInstallComponents: false + enableTektonPipeline: true + enableTektonTriggers: true + enableTektonDashboard: false + enableTektonPruner: false diff --git a/dev/storage-integration/README.md b/dev/storage-integration/README.md new file mode 100644 index 0000000..d79ebbc --- /dev/null +++ b/dev/storage-integration/README.md @@ -0,0 +1,12 @@ +# MyClaim + +This Crossplane Configuration provisions a `StorageIntegration` Composite Resource Definition (XRD) along with a Composition and an example Claim. + +## DEV + +```bash +crossplane render examples/claim.yaml \ +apis/composition.yaml \ +examples/functions.yaml \ +--include-function-results +``` diff --git a/dev/storage-integration/apis/composition.yaml b/dev/storage-integration/apis/composition.yaml new file mode 100644 index 0000000..b6258e7 --- /dev/null +++ b/dev/storage-integration/apis/composition.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: v1beta1 +kind: Composition +metadata: + labels: + crossplane.io/xrd: storageintegrations.resources.stuttgart-things.com + name: storage-integration +spec: + compositeTypeRef: + apiVersion: resources.stuttgart-things.com/v1alpha1 + kind: StorageIntegration + #pipeline: + # - step: + # functionRef: + # name: function-go-templating + # input: + # apiVersion: gotemplating.fn.crossplane.io/v1beta1 + # kind: GoTemplate + # source: Inline + # inline: + # template: | + # apiVersion: + # kind: + # metadata: + # annotations: + # gotemplating.fn.crossplane.io/composition-resource-name: $CLAIMNAME + # gotemplating.fn.crossplane.io/ready: "True" + # - step: + # functionRef: + # name: function-patch-and-transform + # input: + # apiVersion: pt.fn.crossplane.io/v1beta1 + # environment: null + # kind: Resources + # patchSets: [] + # resources: + # - name: + # base: + # apiVersion: + # kind: + # patches: {} diff --git a/dev/storage-integration/apis/definition.yaml b/dev/storage-integration/apis/definition.yaml new file mode 100644 index 0000000..566498b --- /dev/null +++ b/dev/storage-integration/apis/definition.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: apiextensions.crossplane.io/v2 +kind: CompositeResourceDefinition +metadata: + name: storageintegrations.resources.stuttgart-things.com +spec: + group: resources.stuttgart-things.com + defaultCompositeDeletePolicy: Foreground + scope: Namespaced + names: + kind: StorageIntegration + plural: storageintegrations + singular: storageintegration + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + # add spec fields here diff --git a/dev/storage-integration/crossplane.yaml b/dev/storage-integration/crossplane.yaml new file mode 100644 index 0000000..ae6adea --- /dev/null +++ b/dev/storage-integration/crossplane.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: meta.pkg.crossplane.io/v1 +kind: Configuration +metadata: + name: StorageIntegration + annotations: + meta.crossplane.io/maintainer: patrick.hermann@sva.de + meta.crossplane.io/source: https://github.com/stuttgart-things/crossplane + meta.crossplane.io/license: Apache-2.0 + meta.crossplane.io/description: | + manages lifecycle of StorageIntegration w/ crossplane + meta.crossplane.io/readme: | + manages lifecycle of StorageIntegration w/ crossplane +spec: + crossplane: + version: ">=2.13.0" + dependsOn: + - provider: xpkg.upbound.io/crossplane-contrib/provider-helm + version: ">=v0.19.0" diff --git a/dev/storage-integration/examples/claim.yaml b/dev/storage-integration/examples/claim.yaml new file mode 100644 index 0000000..4f320ed --- /dev/null +++ b/dev/storage-integration/examples/claim.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: resources.stuttgart-things.com/v1 +kind: StorageIntegration +metadata: + name: StorageIntegrationClaim + namespace: default +spec: + # add spec fields here diff --git a/dev/storage-integration/examples/functions.yaml b/dev/storage-integration/examples/functions.yaml new file mode 100644 index 0000000..bbbe796 --- /dev/null +++ b/dev/storage-integration/examples/functions.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: pt.fn.crossplane.io/v1beta1 +kind: Function +metadata: + name: function-patch-and-transform +spec: + package: xpkg.upbound.io/function-patch-and-transform:v0.1.0 +--- +apiVersion: gotemplating.fn.crossplane.io/v1beta1 +kind: Function +metadata: + name: function-go-templating +spec: + package: xpkg.upbound.io/function-go-templating:v0.1.0 +--- diff --git a/packages/configurations/cloud-config.yaml b/packages/configurations/cloud-config.yaml index e32e6fe..015824c 100644 --- a/packages/configurations/cloud-config.yaml +++ b/packages/configurations/cloud-config.yaml @@ -4,4 +4,4 @@ kind: Configuration metadata: name: cloud-config spec: - package: ghcr.io/stuttgart-things/crossplane/cloud-config:v0.4.1 + package: ghcr.io/stuttgart-things/crossplane/cloud-config:v0.5.0 diff --git a/tests/in-cluster-helm.yaml b/tests/in-cluster-helm.yaml new file mode 100644 index 0000000..8c076a7 --- /dev/null +++ b/tests/in-cluster-helm.yaml @@ -0,0 +1,38 @@ +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: DeploymentRuntimeConfig +metadata: + name: provider-helm +spec: + serviceAccountTemplate: + metadata: + name: provider-helm +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: provider-helm-cluster-admin +subjects: + - kind: ServiceAccount + name: provider-helm + namespace: crossplane-system +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: helm.crossplane.io/v1beta1 +kind: ProviderConfig +metadata: + name: in-cluster +spec: + credentials: + source: InjectedIdentity +--- +apiVersion: helm.m.crossplane.io/v1beta1 +kind: ClusterProviderConfig +metadata: + name: in-cluster +spec: + credentials: + source: InjectedIdentity diff --git a/tests/in-cluster-k8s.yaml b/tests/in-cluster-k8s.yaml new file mode 100644 index 0000000..af0ccd2 --- /dev/null +++ b/tests/in-cluster-k8s.yaml @@ -0,0 +1,38 @@ +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: DeploymentRuntimeConfig +metadata: + name: provider-kubernetes +spec: + serviceAccountTemplate: + metadata: + name: provider-kubernetes +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: provider-kubernetes-cluster-admin +subjects: + - kind: ServiceAccount + name: provider-kubernetes + namespace: crossplane-system +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: kubernetes.crossplane.io/v1alpha1 +kind: ProviderConfig +metadata: + name: in-cluster +spec: + credentials: + source: InjectedIdentity +--- +apiVersion: kubernetes.m.crossplane.io/v1alpha1 +kind: ClusterProviderConfig +metadata: + name: in-cluster +spec: + credentials: + source: InjectedIdentity