### Multi-Tenant Setup Examples Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagereferencegrant-api.md This section provides examples for a multi-tenant setup, defining separate grants for 'team-a' and 'team-b' to access specific clusters and buckets. It also includes a grant for 'monitoring' access to a metrics bucket. ```yaml # Grant team-a access to cluster and team-a-bucket apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-a namespace: storage-admin spec: from: - kind: GarageKey namespace: team-a - kind: GarageBucket namespace: team-a to: - kind: GarageCluster name: main-cluster - kind: GarageBucket name: team-a-bucket --- # Grant team-b access to cluster and team-b-bucket apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-b namespace: storage-admin spec: from: - kind: GarageKey namespace: team-b - kind: GarageBucket namespace: team-b to: - kind: GarageCluster name: main-cluster - kind: GarageBucket name: team-b-bucket --- # Grant monitoring access to read-only metrics bucket apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-monitoring namespace: storage-admin spec: from: - kind: GarageKey namespace: monitoring to: - kind: GarageBucket name: metrics-bucket ``` -------------------------------- ### Start Local Development Cluster Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Use this command to start a kind cluster and deploy the operator for local development. Ensure you have `kind` and `docker` installed. ```bash make dev-up ``` -------------------------------- ### Create Bucket Example in Operator Controller Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Example of using the client to create a bucket within an operator controller. Handles potential errors during bucket creation. ```go client := garage.NewClient(adminEndpoint, adminToken) bucketInfo, err := client.CreateBucket(ctx, &garage.BucketCreation{ GlobalAlias: spec.GlobalAlias, }) if err != nil { // Handle error } status.BucketID = bucketInfo.ID ``` -------------------------------- ### Permission Layering Example Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Illustrates how default permissions for all buckets and specific bucket permissions are layered. This example shows a monitoring key that reads all buckets and owns the 'metrics-bucket'. ```yaml spec: allBuckets: read: true bucketPermissions: - bucketRef: name: metrics-bucket owner: true ``` -------------------------------- ### Install Garage Operator with COSI Enabled Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Installs the garage-operator Helm chart with the COSI integration enabled. ```bash helm install garage-operator oci://ghcr.io/rajsinghtech/charts/garage-operator \ --namespace garage-operator-system \ --create-namespace \ --set cosi.enabled=true ``` -------------------------------- ### Install k8s-csi-s3 Driver via Helm Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Install the CSI driver using Helm, configuring it to use the GarageKey-created secret and specifying storage class options. Ensure the namespace is created and set `secret.create=false` to utilize the pre-existing Garage secret. ```bash helm repo add csi-s3 https://yandex-cloud.github.io/k8s-csi-s3/charts helm install csi-s3 csi-s3/csi-s3 \ --namespace csi-s3 --create-namespace \ --set storageClass.singleBucket=csi-s3 \ --set 'storageClass.mountOptions=--memory-limit 1000 --dir-mode 0777 --file-mode 0666' \ --set secret.create=false ``` -------------------------------- ### Install Garage Operator from Local Chart Source: https://github.com/rajsinghtech/garage-operator/blob/main/charts/garage-operator/README.md Installs the Garage Operator Helm chart from a local clone of the repository. This method is useful for development or when deploying a modified chart. ```bash git clone https://github.com/rajsinghtech/garage-operator.git cd garage-operator helm install garage-operator charts/garage-operator \ --namespace garage-operator-system \ --create-namespace ``` -------------------------------- ### Install Garage Operator Source: https://github.com/rajsinghtech/garage-operator/blob/main/CLAUDE.md Installs the Garage Operator using the latest release YAML. This is a common first step for deploying the operator. ```bash kubectl apply -f https://github.com/rajsinghtech/garage-operator/releases/latest/download/install.yaml ``` -------------------------------- ### Install Latest Garage Operator from OCI Registry Source: https://github.com/rajsinghtech/garage-operator/blob/main/charts/garage-operator/README.md Installs the latest version of the Garage Operator Helm chart from the GHCR OCI registry. Ensures the operator is installed into its own namespace. ```bash helm install garage-operator oci://ghcr.io/rajsinghtech/charts/garage-operator \ --namespace garage-operator-system \ --create-namespace ``` -------------------------------- ### Importing Existing Credentials (Inline) Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey by importing existing S3 credentials directly specified in the manifest. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: imported-key spec: clusterRef: name: garage name: "Imported Credentials" importKey: accessKeyId: "GKxxxxxxxxxxxxxxxxxxxxxxxx" secretAccessKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` -------------------------------- ### GarageBucket: v1alpha1 keyPermissions Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1alpha1 format for keyPermissions in GarageBucket, where keyRef is a scalar string. ```yaml keyPermissions: - keyRef: my-key read: true write: true ``` -------------------------------- ### Unified Cluster Gateway Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Example configuration for a unified Garage cluster where the gateway tier runs alongside the storage tier. This setup is common for in-cluster deployments. ```yaml apiVersion: garage.garage.io/v1beta2 kind: GarageCluster metadata: name: garage spec: zone: us-east-1 replication: factor: 3 storage: replicas: 3 metadata: size: 10Gi data: size: 100Gi gateway: replicas: 4 resources: requests: cpu: 50m memory: 128Mi admin: adminTokenSecretRef: name: garage-admin-token key: admin-token ``` -------------------------------- ### Basic GarageKey with Specific Bucket Access Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey to grant read and write access to a specific bucket named 'app-data'. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: app-key spec: clusterRef: name: garage name: "Application Storage Key" bucketPermissions: - bucketRef: name: app-data read: true write: true ``` -------------------------------- ### GarageBucket: v1beta1 keyPermissions Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1beta1 format for keyPermissions in GarageBucket, where keyRef is an object with a name field. ```yaml keyPermissions: - keyRef: name: my-key read: true write: true ``` -------------------------------- ### Custom Secret Template Example Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md An example of a custom SecretTemplate configuration. This produces a secret with keys that align with common environment variable naming conventions. ```yaml secretTemplate: name: s3-credentials accessKeyIdKey: AWS_ACCESS_KEY_ID secretAccessKeyKey: AWS_SECRET_ACCESS_KEY endpointKey: AWS_ENDPOINT_URL_S3 regionKey: AWS_REGION includeEndpoint: true includeRegion: true additionalData: BUCKET: my-bucket STORAGE_CLASS: standard ``` -------------------------------- ### GarageKey: v1alpha1 bucketPermissions Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1alpha1 format for bucketPermissions in GarageKey, where bucketRef is a scalar string. ```yaml bucketPermissions: - bucketRef: my-bucket read: true write: true ``` -------------------------------- ### Install COSI CRDs Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Installs the necessary Custom Resource Definitions for COSI. Ensure the COSI_REF is set to a known-good version. ```bash COSI_REF=bf23a024f511482856f047525f732f26c61e2b85 for crd in bucketclaims bucketaccesses bucketclasses bucketaccessclasses buckets; do kubectl apply -f "https://raw.githubusercontent.com/kubernetes-sigs/container-object-storage-interface/${COSI_REF}/client/config/crd/objectstorage.k8s.io_${crd}.yaml" done ``` -------------------------------- ### Importing Existing Credentials (From Secret) Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey by importing existing S3 credentials stored in a Kubernetes secret. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: imported-from-secret spec: clusterRef: name: garage name: "Imported from Secret" importKey: secretRef: name: my-existing-creds accessKeyIdKey: AWS_ACCESS_KEY_ID secretAccessKeyKey: AWS_SECRET_ACCESS_KEY ``` -------------------------------- ### GarageKey: v1beta1 bucketPermissions Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1beta1 format for bucketPermissions in GarageKey, where bucketRef is an object with a name field. ```yaml bucketPermissions: - bucketRef: name: my-bucket read: true write: true ``` -------------------------------- ### Annotate Bucket for MPU Cleanup Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagebucket-api.md Example of annotating a GarageBucket resource to trigger cleanup of incomplete multipart uploads and set an age threshold for the cleanup. ```bash kubectl annotate garagebucket my-bucket \ garage.rajsingh.info/cleanup-mpu=true \ garage.rajsingh.info/cleanup-mpu-older-than=48h ``` -------------------------------- ### Cross-Namespace Access with GarageReferenceGrant Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example demonstrating cross-namespace access configuration. It includes a GarageReferenceGrant in the storage-admin namespace and a GarageKey in 'team-a' namespace referencing resources in 'storage-admin'. ```yaml # In storage-admin namespace apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-a namespace: storage-admin spec: from: - kind: GarageKey namespace: team-a to: - kind: GarageCluster name: garage - kind: GarageBucket name: team-a-bucket --- # In team-a namespace apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: team-a-key namespace: team-a spec: clusterRef: name: garage namespace: storage-admin bucketPermissions: - bucketRef: name: team-a-bucket namespace: storage-admin read: true write: true ``` -------------------------------- ### GarageCluster: v1alpha1 admin configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1alpha1 admin configuration in GarageCluster, showing enabled and bindPort fields. ```yaml admin: enabled: true bindPort: 3903 adminTokenSecretRef: name: garage-admin-token key: admin-token ``` -------------------------------- ### GarageCluster: v1beta1 admin configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1beta1 admin configuration in GarageCluster, where enabled and bindPort are removed. ```yaml admin: adminTokenSecretRef: name: garage-admin-token key: admin-token ``` -------------------------------- ### Install Specific Garage Operator Version from OCI Registry Source: https://github.com/rajsinghtech/garage-operator/blob/main/charts/garage-operator/README.md Installs a specific version of the Garage Operator Helm chart from the GHCR OCI registry. This is useful for deploying a known stable version or for testing. ```bash helm install garage-operator oci://ghcr.io/rajsinghtech/charts/garage-operator \ --version \ --namespace garage-operator-system \ --create-namespace ``` -------------------------------- ### Gateway Node Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagenode-api.md Example YAML configuration for creating a gateway node in Manual layout mode. Set 'gateway: true' and omit or leave 'capacity' unset. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageNode metadata: name: gateway-node spec: clusterRef: name: garage zone: zone-a gateway: true storage: metadata: size: 1Gi ``` -------------------------------- ### Get Garage Resources and Operator Logs Source: https://github.com/rajsinghtech/garage-operator/blob/main/charts/garage-operator/templates/NOTES.txt Commands to view all Garage resources and stream the operator's logs. ```bash kubectl get garageclusters,garagebuckets,garagekeys,garagenodes kubectl logs -n {{ .Release.Namespace }} -l app.kubernetes.io/name={{ include "garage-operator.name" . }} -f ``` -------------------------------- ### GarageCluster and GarageNode Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagenode-api.md Example of setting up a GarageCluster with Manual layout policy and creating individual GarageNode resources. Ensure the cluster is configured with Manual layout policy before creating storage nodes. ```yaml apiVersion: garage.rajsingh.info/v1beta2 kind: GarageCluster metadata: name: garage spec: layoutPolicy: Manual zone: us-east-1 replication: factor: 3 network: rpcSecretRef: name: garage-rpc-secret key: rpc-secret admin: adminTokenSecretRef: name: garage-admin-token key: admin-token --- # Create individual storage nodes apiVersion: garage.rajsingh.info/v1beta1 kind: GarageNode metadata: name: storage-node-0 spec: clusterRef: name: garage zone: zone-a capacity: 500Gi storage: metadata: size: 10Gi data: size: 500Gi --- apiVersion: garage.rajsingh.info/v1beta1 kind: GarageNode metadata: name: storage-node-1 spec: clusterRef: name: garage zone: zone-b capacity: 500Gi storage: metadata: size: 10Gi data: size: 500Gi ``` -------------------------------- ### Allow Multiple Resource Types to Be Referenced Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagereferencegrant-api.md This example demonstrates how to grant access to multiple types of Garage resources. It allows GarageKeys and GarageBuckets from 'team-a' to reference both a specific GarageCluster and a specific GarageBucket. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-a namespace: storage-admin spec: from: - kind: GarageKey namespace: team-a - kind: GarageBucket namespace: team-a to: - kind: GarageCluster name: my-cluster - kind: GarageBucket name: team-a-bucket ``` -------------------------------- ### Provision Per-Pod Gateway Service (Tailscale) Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of provisioning a LoadBalancer Service for a specific gateway pod using Tailscale annotations. This ensures that traffic is directed to the correct gateway instance. ```yaml apiVersion: v1 kind: Service metadata: name: garage-gateway-0-ts annotations: tailscale.com/hostname: ottawa-garage-gw-0 spec: loadBalancerClass: tailscale selector: statefulset.kubernetes.io/pod-name: garage-gateway-0 ports: - name: rpc port: 3901 ``` -------------------------------- ### Requeue Behavior Example Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/controller-reconcilers.md Demonstrates error and periodic requeue strategies for controllers. Transient errors trigger a fast retry, while successful operations schedule a periodic requeue. ```go if err != nil { if garage.IsServiceUnavailable(err) { return ctrl.Result{RequeueAfter: 5 * time.Second}, nil // Transient; fast retry } return ctrl.Result{}, err // Exponential backoff } // Success return ctrl.Result{RequeueAfter: 5 * time.Minute}, nil ``` -------------------------------- ### Get Staging Area Layout Version Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Retrieves the version number of the next layout that is ready to be applied from the staging area. ```go func (c *Client) StagedLayoutVersion(ctx context.Context) (int, error) ``` -------------------------------- ### Get All Garage Clusters Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Retrieve all Garage clusters and observe the 'Diagnosis' column for a quick health summary. ```bash kubectl get gc ``` -------------------------------- ### GarageKey for Cluster-Wide Read-Only Access Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey to grant read-only access to all buckets within the cluster. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: backup-reader spec: clusterRef: name: garage name: "Backup Read-Only Key" allBuckets: read: true ``` -------------------------------- ### GarageKey with Owner Permissions on Specific Bucket Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey that grants owner permissions (read, write, owner) to a specific bucket named 'metrics-bucket'. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: metrics-key spec: clusterRef: name: garage allBuckets: read: true bucketPermissions: - bucketRef: name: metrics-bucket write: true owner: true ``` -------------------------------- ### Garage Operator Development Commands Source: https://github.com/rajsinghtech/garage-operator/blob/main/CLAUDE.md Common commands for setting up, testing, and managing the Garage Kubernetes Operator during development. These include cluster setup, applying test resources, viewing status, streaming logs, reloading the operator, running locally for debugging, and tearing down the cluster. ```bash make dev-up # Setup: kind + CRDs + operator make dev-test # Apply test resources make dev-status # View all garage resources make dev-logs # Stream operator logs make dev-load # Rebuild and reload operator make dev-run # Run operator locally (debugging) make dev-down # Tear down cluster ``` -------------------------------- ### Separate Grants for Cluster and Buckets Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagereferencegrant-api.md This example shows how to create distinct GarageReferenceGrants for different resource types. One grant allows access to a specific cluster, while another allows access to specific buckets, providing fine-grained control. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-a-cluster namespace: storage-admin spec: from: - kind: GarageKey namespace: team-a to: - kind: GarageCluster name: my-cluster --- apiVersion: garage.rajsingh.info/v1beta1 kind: GarageReferenceGrant metadata: name: allow-team-a-buckets namespace: storage-admin spec: from: - kind: GarageKey namespace: team-a to: - kind: GarageBucket name: team-a-bucket - kind: GarageBucket name: shared-bucket ``` -------------------------------- ### Local Development Commands Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/README.md Commands to manage a local Kind cluster for operator development. Use these to start, test, view status, stream logs, and tear down the cluster. ```bash make dev-up # Start local Kind cluster with operator make dev-test # Apply test resources make dev-status # View cluster resources make dev-logs # Stream operator logs make dev-down # Tear down cluster ``` -------------------------------- ### Initialize Garage Admin API Client Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Creates a new Garage Admin API client instance. Requires the base URL of the API and an admin token. ```go client := garage.NewClient( "http://garage:3903", "abcdef123456.secret123456789", ) ``` -------------------------------- ### Install Garage Operator with Webhooks Disabled Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Installs the Garage Operator with admission and conversion webhooks disabled. This is useful for local development or v1beta2-only installations. ```bash helm install garage-operator oci://ghcr.io/rajsinghtech/charts/garage-operator \ --namespace garage-operator-system \ --create-namespace \ --set webhooks.enabled=false ``` -------------------------------- ### Garage Admin API Client Initialization Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/MANIFEST.txt Demonstrates how to initialize the Garage Admin API v2 client. This client is used for interacting with the Garage system programmatically. ```go package main import ( "context" "log" "internal/garage/client" ) func main() { ctx := context.Background() // Initialize the client with default configuration garageClient, err := client.NewClient(client.WithConfigPath("/etc/garage/config.yaml")) if err != nil { log.Fatalf("Failed to create Garage client: %v", err) } log.Println("Garage client initialized successfully") // Now you can use garageClient to perform operations // For example: clusterStatus, err := garageClient.Cluster.GetStatus(ctx, "example-cluster") } ``` -------------------------------- ### Enable Website Hosting with Custom Domain Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Configure a custom root domain for website hosting. Buckets with website hosting enabled are served at `.` on port 3902. Point DNS to the Garage service. ```yaml spec: webApi: rootDomain: ".web.garage.example.com" ``` ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageBucket metadata: name: my-site spec: clusterRef: name: garage website: enabled: true indexDocument: index.html errorDocument: error.html ``` -------------------------------- ### WebsiteConfig Structure Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagebucket-api.md Configures static website hosting for a bucket, including enabling it and specifying index/error documents. When enabled, the bucket is served at a specific address. ```go type WebsiteConfig struct { Enabled *bool IndexDocument string ErrorDocument string } ``` -------------------------------- ### Bucket with Website Hosting Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagebucket-api.md Configure a bucket for static website hosting, specifying index and error documents. This is useful for serving web content directly from the bucket. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageBucket metadata: name: my-site spec: clusterRef: name: garage globalAlias: my-site website: enabled: true indexDocument: index.html errorDocument: error.html quotas: maxSize: 100Gi ``` -------------------------------- ### Get GarageNodes Status Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Use `kubectl get garagenodes` to view the status of all configured GarageNodes, including their cluster, zone, capacity, gateway status, and age. ```bash kubectl get garagenodes # NAME CLUSTER ZONE CAPACITY GATEWAY CONNECTED INLAYOUT AGE # storage-node-a garage zone-a 500Gi false true true 5m ``` -------------------------------- ### Basic Bucket with Quotas Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagebucket-api.md Create a basic bucket with defined size and object quotas. Ensure the cluster reference is correctly set. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageBucket metadata: name: my-bucket spec: clusterRef: name: garage quotas: maxSize: 10Gi maxObjects: 1000000 ``` -------------------------------- ### SetWorker Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Controls the scrub worker, allowing it to be started, paused, resumed, or cancelled. ```APIDOC ## SetWorker ### Description Controls scrub worker. Available commands are `start`, `pause`, `resume`, `cancel`. ### Parameters #### Path Parameters - **worker** (string) - Required - Specifies the worker to control. - **command** (string) - Required - The command to execute on the worker. One of `start`, `pause`, `resume`, `cancel`. ``` -------------------------------- ### Client Initialization Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Creates a new Garage Admin API client. The client is used to interact with the Garage Admin API for managing various resources. ```APIDOC ## NewClient ### Description Creates a new Garage Admin API client. ### Signature ```go func NewClient(baseURL, adminToken string) *Client ``` ### Parameters #### Path Parameters - **baseURL** (string) - Required - Base URL of the Garage Admin API (e.g., `http://garage:3903`) - **adminToken** (string) - Required - Admin API token in format `<24-hex-prefix>.` ### Returns - `*Client` instance ### Request Example ```go client := garage.NewClient( "http://garage:3903", "abcdef123456.secret123456789", ) ``` ``` -------------------------------- ### GarageCluster: v1alpha1 replication Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1alpha1 replication configuration in GarageCluster, including zoneRedundancy. ```yaml replication: factor: 3 zoneRedundancy: "AtLeast(2)" ``` -------------------------------- ### GarageCluster: v1beta1 replication Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of the v1beta1 replication configuration in GarageCluster, using zoneRedundancyMode and zoneRedundancyMinZones. ```yaml replication: factor: 3 zoneRedundancyMode: "AtLeast" zoneRedundancyMinZones: 2 ``` -------------------------------- ### Helm Status and Get Commands Source: https://github.com/rajsinghtech/garage-operator/blob/main/charts/garage-operator/templates/NOTES.txt Commands to check the status and retrieve all information about a Helm release. ```bash helm status {{ .Release.Name }} helm get all {{ .Release.Name }} ``` -------------------------------- ### Create Garage Key with Specific Bucket Permissions Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Creates access credentials ('my-key') granting read and write permissions to the 'my-bucket'. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: my-key spec: clusterRef: name: garage bucketPermissions: - bucketRef: name: my-bucket read: true write: true ``` -------------------------------- ### Control Scrub Worker Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Controls the scrub worker by sending commands like 'start', 'pause', 'resume', or 'cancel'. ```go func (c *Client) SetWorker(ctx context.Context, worker, command string) error ``` -------------------------------- ### Migrate Garage Objects (Python Script) Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md This script migrates GarageKey and GarageBucket objects in-place by converting string references to object references. It requires kubectl and operates on a specified cluster context and namespaces. ```python #!/usr/bin/env python3 import json, subprocess, sys CONTEXT = sys.argv[1] # e.g. my-cluster for namespace in (sys.argv[2:] or ['default']): # Migrate GarageKey: bucketRef string → object result = subprocess.run( ['kubectl', '--context', CONTEXT, 'get', 'garagekey', '-n', namespace, '-o', 'json'], capture_output=True ) data = json.loads(result.stdout) for item in data['items']: changed = False for bp in item.get('spec', {}).get('bucketPermissions', []): if isinstance(bp.get('bucketRef'), str): bp['bucketRef'] = {'name': bp['bucketRef']} changed = True if changed: item['metadata'].pop('managedFields', None) item['metadata'].pop('resourceVersion', None) subprocess.run( ['kubectl', '--context', CONTEXT, 'replace', '-n', namespace, '-f', '-'], input=json.dumps(item).encode() ) print(f"Migrated GarageKey/{item['metadata']['name']}") # Migrate GarageBucket: keyRef string → object result = subprocess.run( ['kubectl', '--context', CONTEXT, 'get', 'garagebucket', '-n', namespace, '-o', 'json'], capture_output=True ) data = json.loads(result.stdout) for item in data['items']: changed = False for kp in item.get('spec', {}).get('keyPermissions', []): if isinstance(kp.get('keyRef'), str): kp['keyRef'] = {'name': kp['keyRef']} changed = True if changed: item['metadata'].pop('managedFields', None) item['metadata'].pop('resourceVersion', None) subprocess.run( ['kubectl', '--context', CONTEXT, 'replace', '-n', namespace, '-f', '-'], input=json.dumps(item).encode() ) print(f"Migrated GarageBucket/{item['metadata']['name']}") ``` -------------------------------- ### Get Background Worker State Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Retrieves the current state of background workers, such as those involved in resync or scrub operations. ```go func (c *Client) GetWorkerInfo(ctx context.Context) (*WorkerState, error) ``` -------------------------------- ### Using Generated Secret in Workload Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of a Kubernetes Pod definition that uses a GarageKey-generated secret ('app-key') for environment variables. ```yaml apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: myapp:latest envFrom: - secretRef: name: app-key # Generated by GarageKey controller env: - name: BUCKET value: app-data ``` -------------------------------- ### Database Configuration Structure Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Defines the configuration options for different database engines supported by the Garage Cluster. Use 'lmdb' for memory-mapped performance, 'sqlite' for file-based storage, or 'fjall' for a newer alternative. ```go type DatabaseConfig struct { Engine string LMDBMapSize *resource.Quantity FjallBlockCacheSize *resource.Quantity } ``` -------------------------------- ### CRD Update Error Message Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of an error message encountered when updating the GarageBucket CRD due to storage version conflicts. ```text CustomResourceDefinition.apiextensions.k8s.io "garagebuckets.garage.rajsingh.info" is invalid: status.storedVersions[0]: Invalid value: "v1alpha1": missing from spec.versions ``` -------------------------------- ### Get Specific Cluster Conditions Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Fetch the detailed status conditions for a specific Garage cluster named 'garage' in JSON format. ```bash kubectl get gc garage -o jsonpath='{.status.conditions}' ``` -------------------------------- ### Import Garage Key from Inline Credentials Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Creates a Garage key by importing provided access key ID and secret access key directly within the manifest. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: imported-key spec: clusterRef: name: garage importKey: accessKeyId: "GKxxxxxxxxxxxxxxxxxxxxxxxx" secretAccessKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` -------------------------------- ### Get Specific Node Information Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Retrieves detailed information about a particular node within the cluster using its unique node ID. ```go func (c *Client) GetNodeInfo(ctx context.Context, nodeID string) (*NodeInfo, error) ``` -------------------------------- ### Create a New Bucket Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Creates a new bucket within the cluster. Optionally, a global alias can be provided during creation. Returns bucket information upon success. ```go func (c *Client) CreateBucket(ctx context.Context, req *BucketCreation) (*BucketInfo, error) ``` -------------------------------- ### Get Cluster Status Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Retrieves the overall status and layout information of the cluster. This is a comprehensive call that provides detailed cluster data. ```go func (c *Client) GetCluster(ctx context.Context) (*Cluster, error) ``` -------------------------------- ### Control Scrub Worker Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Manage the block integrity scrub worker using this annotation. You can start, pause, resume, or cancel the scrub operation. ```bash kubectl annotate garagecluster garage garage.rajsingh.info/scrub-command=start # Later... kubectl annotate garagecluster garage garage.rajsingh.info/scrub-command=pause ``` -------------------------------- ### GarageCluster Controller: Reconcile Gateway Tier Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/controller-reconcilers.md Manages the reconciliation of gateway StatefulSets for unified gateways or the setup of edge gateways using 'connectTo'. ```go reconcileGatewayTierIfNeeded ``` -------------------------------- ### Enable K2V API Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Add `k2vApi` to your spec to enable the K2V API. The `bindPort` defaults to 3904. Omit `k2vApi` to disable. ```yaml spec: k2vApi: bindPort: 3904 # default ``` -------------------------------- ### Manual Layout GarageCluster and GarageNode CRs Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Example of a GarageCluster in Manual layout policy and a GarageNode CR. The GarageCluster spec.storage.replicas is ignored in Manual mode. ```yaml apiVersion: garage.rajsingh.info/v1beta2 kind: GarageCluster metadata: { name: my-cluster } spec: layoutPolicy: Manual replication: { factor: 3, consistencyMode: consistent } admin: adminTokenSecretRef: { name: my-cluster-admin-token, key: admin-token } storage: replicas: 0 # podTemplate fields here become defaults for any GarageNode that # does not set its own (resources, securityContext, nodeSelector, ...). --- apiVersion: garage.rajsingh.info/v1beta1 kind: GarageNode metadata: { name: my-cluster-n1 } spec: clusterRef: { name: my-cluster } zone: rack-1 capacity: 5Ti storage: metadata: { size: 100Gi, storageClassName: fast-ssd } data: { size: 5Ti, storageClassName: bulk } ``` -------------------------------- ### Configure Website Hosting Options Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Set additional options for the web API, such as the bind port and whether to add host to metrics. The default bind port is 3902. ```yaml spec: webApi: rootDomain: ".web.garage.example.com" bindPort: 8080 # default: 3902 addHostToMetrics: true # adds domain to Prometheus labels ``` -------------------------------- ### Custom Secret Template for Environment Variables Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagekey-api.md Example of creating a GarageKey with a custom secret template to define environment variable names for credentials and endpoint. ```yaml apiVersion: garage.rajsingh.info/v1beta1 kind: GarageKey metadata: name: env-key spec: clusterRef: name: garage name: "Environment-friendly Key" bucketPermissions: - bucketRef: name: my-bucket read: true write: true secretTemplate: name: s3-env accessKeyIdKey: AWS_ACCESS_KEY_ID secretAccessKeyKey: AWS_SECRET_ACCESS_KEY endpointKey: AWS_ENDPOINT_URL_S3 regionKey: AWS_REGION includeEndpoint: true includeRegion: false ``` -------------------------------- ### List All Buckets Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garage-admin-client.md Retrieves a list of all buckets currently present in the cluster. ```go func (c *Client) ListBuckets(ctx context.Context) ([]BucketInfo, error) ``` -------------------------------- ### Web API Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Configures the Web API server for static website hosting, including enablement, domain, port, and address. ```APIDOC ## API Configuration ### WebAPIConfig This section details the configuration for the Web API server, primarily for static website hosting. #### Parameters - **enabled** (*bool) - Optional - Enable static website hosting. Defaults to true. - **rootDomain** (string) - Optional - Root domain for bucket websites. Defaults to '...svc'. - **bindPort** (int32) - Optional - Website hosting server port. Defaults to 3902. - **bindAddress** (string) - Optional - Custom bind address. - **addHostToMetrics** (bool) - Optional - Add domain name to Prometheus metrics labels. Defaults to false. ``` -------------------------------- ### PublicEndpointConfig Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Configures how remote clusters reach this cluster's nodes for RPC connectivity in federated setups. It allows specifying different types of endpoint exposure. ```APIDOC ## PublicEndpointConfig ### Description Configures how remote clusters reach this cluster's nodes for RPC connectivity in federated setups. It allows specifying different types of endpoint exposure. ### Parameters #### Request Body - **type** (string) - Required - Endpoint type: `LoadBalancer`, `NodePort`, `ExternalIP`, or `Headless` - **loadBalancer** (LoadBalancerEndpointConfig) - Optional - Configuration for LoadBalancer-type exposure - **nodePort** (NodePortEndpointConfig) - Optional - Configuration for NodePort-type exposure - **externalIP** (ExternalIPEndpointConfig) - Optional - Configuration for ExternalIP-type exposure ``` -------------------------------- ### K2V API Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Configures the K2V API server, including bind port and address. Omit to disable. ```APIDOC ## API Configuration ### K2VAPIConfig This section details the configuration for the K2V API server. Omit this configuration entirely to disable K2V. #### Parameters - **bindPort** (int32) - Optional - K2V API server port. Defaults to 3904. - **bindAddress** (string) - Optional - Custom bind address for K2V API. ``` -------------------------------- ### Web API Configuration Structure Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Defines the configuration for the Web API server, controlling static website hosting, domain, ports, and metrics. ```Go type WebAPIConfig struct { Enabled *bool RootDomain string BindPort int32 BindAddress string AddHostToMetrics bool } ``` -------------------------------- ### Block Storage Configuration Structure Source: https://github.com/rajsinghtech/garage-operator/blob/main/_autodocs/garagecluster-api.md Specifies parameters for configuring block storage, including data block size, buffering, concurrency limits, and compression. Options to disable scrubbing and use local time for workers are also available. ```go type BlockConfig struct { Size *resource.Quantity RAMBufferMax *resource.Quantity MaxConcurrentReads *int MaxConcurrentWritesPerRequest *int CompressionLevel *string DisableScrub bool UseLocalTZ bool } ``` -------------------------------- ### Edge Gateway Configuration Source: https://github.com/rajsinghtech/garage-operator/blob/main/README.md Example configuration for an edge-only Garage cluster that connects to a remote storage cluster. This is used for gateways in separate K8s clusters or external environments. ```yaml apiVersion: garage.garage.io/v1beta2 kind: GarageCluster metadata: name: garage-edge spec: replication: factor: 3 gateway: replicas: 3 rpcPublicAddr: "edge-gateway.tailnet.example:3901" connectTo: rpcSecretRef: name: garage-rpc-secret key: rpc-secret adminApiEndpoint: "http://garage-primary.tailnet.example:3903" adminTokenSecretRef: name: storage-admin-token key: admin-token admin: adminTokenSecretRef: name: gateway-admin-token key: admin-token publicEndpoint: type: NodePort nodePort: basePort: 30901 externalAddresses: - "edge-node1.example.com" - "edge-node2.example.com" ``` -------------------------------- ### Migrate from Two-CR to Unified Schema Source: https://github.com/rajsinghtech/garage-operator/blob/main/MIGRATION.md Steps to migrate an existing deployment from separate garage (storage) and garage-gateway CRs to the new unified GarageCluster CR. Delete the old gateway CR first to avoid conflicts. ```bash NAMESPACE=garage-operator-system # 1. Delete the old gateway CR FIRST. Otherwise the new combined CR's gateway # tier and the old gateway StatefulSet will both try to manage the same # layout entries. kubectl -n "$NAMESPACE" delete garagecluster garage-gateway # 2. The old gateway StatefulSet's metadata PVCs become orphaned because they # were owned by the deleted GarageCluster. Delete them manually: kubectl -n "$NAMESPACE" get pvc -l app.kubernetes.io/instance=garage-gateway kubectl -n "$NAMESPACE" delete pvc -l app.kubernetes.io/instance=garage-gateway # 3. Apply the new combined CR with both tiers: kubectl apply -f garage-combined.yaml ```