Skip to content

Project Setup

This page documents the monorepo layout, Go workspace configuration, and developer tooling for building CobaltCore operators.

Go Workspace

CobaltCore uses a Go Workspace (go.work) to manage multiple operator modules alongside a shared library in a single repository. This avoids the overhead of separate repositories and tagged releases for shared code — all operators develop against the same internal/common/ revision at all times.

go
// go.work
go 1.25

use (
    ./internal/common
    ./operators/keystone
    ./operators/glance
    ./operators/placement
    ./operators/nova
    ./operators/neutron
    ./operators/cinder
    ./operators/c5c3
)

Each use directive points to a Go module with its own go.mod. The workspace ensures that internal/common is resolved locally rather than fetched from a registry.

Operator SDK Initialization

Each operator is scaffolded with Operator SDK:

bash
cd operators/keystone
operator-sdk init \
  --domain openstack.c5c3.io \
  --repo github.com/c5c3/forge/operators/keystone

operator-sdk create api \
  --group keystone \
  --version v1alpha1 \
  --kind Keystone \
  --resource --controller

This generates the base project structure: main.go, api/v1alpha1/ types, internal/controller/ reconciler, and Kubebuilder configuration.

Monorepo Directory Structure

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                       MONOREPO LAYOUT                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  c5c3/forge/                                                                │
│  ├── go.work                          # Go Workspace root                   │
│  ├── Makefile                         # Top-level build targets             │
│  │                                                                          │
│  ├── internal/                                                              │
│  │   └── common/                      # Shared library                      │
│  │       ├── go.mod                   # module: github.com/c5c3/forge/      │
│  │       │                            #   internal/common                   │
│  │       ├── conditions/              # Condition helpers                   │
│  │       ├── config/                  # INI config rendering                │
│  │       ├── database/                # MariaDB CR interaction              │
│  │       ├── deployment/              # Deployment/Service helpers          │
│  │       ├── job/                     # Job/CronJob management              │
│  │       ├── secrets/                 # ESO secret readiness, PushSecret    │
│  │       ├── plugins/                 # Plugin/middleware framework         │
│  │       ├── tls/                     # cert-manager integration            │
│  │       └── types/                   # Shared Go type definitions          │
│  │                                                                          │
│  ├── operators/                                                             │
│  │   ├── keystone/                    # Keystone Operator                   │
│  │   │   ├── go.mod                                                         │
│  │   │   ├── main.go                                                        │
│  │   │   ├── api/v1alpha1/            # CRD types + webhooks                │
│  │   │   │   ├── keystone_types.go                                          │
│  │   │   │   ├── keystone_webhook.go                                        │
│  │   │   │   └── zz_generated.deepcopy.go                                   │
│  │   │   ├── internal/controller/     # Reconciler                          │
│  │   │   │   ├── keystone_controller.go                                     │
│  │   │   │   └── keystone_controller_test.go                                │
│  │   │   ├── config/                  # Kubebuilder metadata                │
│  │   │   │   ├── crd/                                                       │
│  │   │   │   ├── rbac/                                                      │
│  │   │   │   └── manager/                                                   │
│  │   │   └── helm/                    # Helm chart                          │
│  │   │       └── keystone-operator/                                         │
│  │   ├── glance/                      # (same structure)                    │
│  │   ├── nova/                        # (same structure)                    │
│  │   └── ...                                                                │
│  │                                                                          │
│  ├── tests/                                                                 │
│  │   └── e2e/                         # Chainsaw E2E tests                  │
│  │       ├── chainsaw-config.yaml                                           │
│  │       └── keystone/                                                      │
│  │           ├── basic-deployment/                                          │
│  │           ├── fernet-rotation/                                           │
│  │           └── ...                                                        │
│  │                                                                          │
│  └── releases/                        # Per-release configuration           │
│      └── 2025.2/                                                            │
│          ├── source-refs.yaml         # Git refs for container builds       │
│          └── extra-packages.yaml      # Additional Python packages          │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Module Dependencies

Each operator module references the shared library via a replace directive for local development:

go
// operators/keystone/go.mod
module github.com/c5c3/forge/operators/keystone

go 1.25

require (
    github.com/c5c3/forge/internal/common v0.0.0
    sigs.k8s.io/controller-runtime v0.23.1
    k8s.io/apimachinery v0.35.1
    k8s.io/client-go v0.35.1
)

replace github.com/c5c3/forge/internal/common => ../../internal/common

Note: The replace directive is only relevant when building outside the Go Workspace (e.g., in CI without go.work). Within the workspace, go.work's use directive takes precedence.

Makefile Targets

The top-level Makefile orchestrates builds across all operators:

TargetDescription
make generateRun controller-gen to generate DeepCopy methods and CRD manifests for all operators
make manifestsGenerate CRD, RBAC, and webhook manifests into config/ directories
make buildCompile all operator binaries
make testRun unit tests across all modules (see Testing)
make test-integrationRun envtest integration tests (see Testing)
make docker-buildBuild container images for all operators
make helm-packagePackage Helm charts for all operators (see CI/CD & Packaging)
make lintRun golangci-lint across all modules
make e2eRun Chainsaw E2E tests against a live cluster (see Testing)

Individual operators can be targeted via the OPERATOR variable:

bash
make build OPERATOR=keystone
make test OPERATOR=keystone
make docker-build OPERATOR=keystone

Developer Prerequisites

ToolVersionPurpose
Go1.25+Build and test
operator-sdk1.38+Project scaffolding
controller-gen0.16+CRD/RBAC/DeepCopy generation
kind0.24+Local Kubernetes cluster for testing
chainsaw0.2+E2E test execution
helm3.xChart packaging
golangci-lint2.10+Linting
docker / podmanContainer image builds
kubectl1.35+Cluster interaction