Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions osac-operator/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ OSAC operator is a Kubernetes operator that reconciles infrastructure resources
- **ExternalIP** — external IP allocated from ExternalIPPool
- **ExternalIPAttachment** — attachment of ExternalIP to ComputeInstance
- **NATGateway** — outbound SNAT for a VirtualNetwork
- **Volume** (`vol`) — block storage on vendor arrays via CSI

## Critical Rules

Expand Down
2 changes: 2 additions & 0 deletions osac-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ custom resources and reconciles them to their desired state:
- **Subnet** (`subnet`) — represents a subnet within a VirtualNetwork.
- **SecurityGroup** (`sg`) — defines network security (firewall) rules with
ingress/egress rules, protocols, port ranges, and CIDR blocks.
- **Volume** (`vol`) — provisions block storage on vendor arrays via the
VendorProvisioner interface (vendor CSI controllers).

## Configuration

Expand Down
39 changes: 0 additions & 39 deletions osac-operator/api/v1alpha1/volume_names.go

This file was deleted.

4 changes: 4 additions & 0 deletions osac-operator/api/v1alpha1/volume_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ const (
)

// VolumeProtocol defines valid storage protocols for volumes.
// When adding a value here, also add it to the kubebuilder Enum below, to the
// crdProtocolToProto switch in internal/controller/volume_feedback_controller.go,
// and to allVolumeProtocols in that controller's test (which fails if the switch
// is left incomplete).
// +kubebuilder:validation:Enum=Block;NFS
type VolumeProtocol string

Expand Down
3 changes: 3 additions & 0 deletions osac-operator/charts/operator/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ rules:
- subnets
- tenants
- virtualnetworks
- volumes
verbs:
- create
- delete
Expand All @@ -114,6 +115,7 @@ rules:
- subnets/finalizers
- tenants/finalizers
- virtualnetworks/finalizers
- volumes/finalizers
verbs:
- update
- apiGroups:
Expand All @@ -130,6 +132,7 @@ rules:
- subnets/status
- tenants/status
- virtualnetworks/status
- volumes/status
verbs:
- get
- patch
Expand Down
6 changes: 6 additions & 0 deletions osac-operator/charts/operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: OSAC_VOLUME_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: OSAC_ENABLE_CLUSTER_CONTROLLER
value: {{ .Values.controllers.clusterOrder | quote }}
- name: OSAC_ENABLE_COMPUTE_INSTANCE_CONTROLLER
Expand All @@ -106,6 +110,8 @@ spec:
value: {{ .Values.controllers.bareMetalInstance | quote }}
- name: OSAC_ENABLE_STORAGE_CONTROLLER
value: {{ .Values.controllers.storage | quote }}
- name: OSAC_ENABLE_VOLUME_CONTROLLER
value: {{ .Values.controllers.volume | quote }}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rules:
- subnets
- tenants
- virtualnetworks
- volumes
verbs:
- create
- delete
Expand All @@ -44,6 +45,7 @@ rules:
- subnets/status
- tenants/status
- virtualnetworks/status
- volumes/status
verbs:
- get
- apiGroups:
Expand Down
4 changes: 4 additions & 0 deletions osac-operator/charts/operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ controllers:
networking: true
bareMetalInstance: true
storage: true
# Disabled until OSAC-4138 wires the vendor CSI provisioner; enabling it now
# would only leave Volumes stuck in CREATING (nil provisioner). Flip to true
# as part of OSAC-4138.
volume: false

configSecret:
name: "osac-config"
Expand Down
130 changes: 92 additions & 38 deletions osac-operator/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const (
envClusterOrderNamespace = "OSAC_CLUSTER_ORDER_NAMESPACE"
envAgentNamespace = "OSAC_AGENT_NAMESPACE"
envBareMetalInstanceNamespace = "OSAC_BARE_METAL_INSTANCE_NAMESPACE"
envVolumeNamespace = "OSAC_VOLUME_NAMESPACE"

// AAP configuration
envAAPURL = "OSAC_AAP_URL"
Expand Down Expand Up @@ -118,6 +119,7 @@ const (
// Controller enable flags (defaults when flag is not set)
envEnableTenantController = "OSAC_ENABLE_TENANT_CONTROLLER"
envEnableStorageController = "OSAC_ENABLE_STORAGE_CONTROLLER"
envEnableVolumeController = "OSAC_ENABLE_VOLUME_CONTROLLER"
envEnableComputeInstanceController = "OSAC_ENABLE_COMPUTE_INSTANCE_CONTROLLER"
envEnableClusterController = "OSAC_ENABLE_CLUSTER_CONTROLLER"
envEnableNetworkingController = "OSAC_ENABLE_NETWORKING_CONTROLLER"
Expand All @@ -136,6 +138,7 @@ const (
type controllerFlags struct {
Tenant bool
Storage bool
Volume bool
ComputeInstance bool
Cluster bool
Networking bool
Expand All @@ -151,7 +154,10 @@ func registerControllerFlags() *controllerFlags {
"Enable the tenant controller.")
flag.BoolVar(&flags.Storage, "enable-storage-controller",
helpers.GetEnvWithDefault(envEnableStorageController, false),
"Enable the storage controller.")
"Enable the storage controller (tenant StorageClass management, ClusterOrder storage provisioning).")
flag.BoolVar(&flags.Volume, "enable-volume-controller",
helpers.GetEnvWithDefault(envEnableVolumeController, false),
"Enable the volume controller (block volume provisioning via vendor CSI).")
flag.BoolVar(&flags.ComputeInstance, "enable-compute-instance-controller",
helpers.GetEnvWithDefault(envEnableComputeInstanceController, false),
"Enable the compute-instance controller.")
Expand All @@ -168,15 +174,21 @@ func registerControllerFlags() *controllerFlags {
}

// enableAllIfNoneSet enables all controllers if none are explicitly enabled.
//
// The Volume controller is intentionally excluded: its VendorProvisioner is a
// nil stub until OSAC-4138 wires the real vendor CSI client, so enabling it
// would only leave Volumes stuck in Progressing/CREATING with no path to
// success. It stays opt-in (--enable-volume-controller) until then. OSAC-4138
// adds it back here and flips controllers.volume to true in the Helm values.
func (f *controllerFlags) enableAllIfNoneSet() {
if !f.Tenant && !f.Storage && !f.ComputeInstance && !f.Cluster && !f.Networking && !f.BareMetalInstance {
if !f.Tenant && !f.Storage && !f.Volume && !f.ComputeInstance && !f.Cluster && !f.Networking && !f.BareMetalInstance {
f.Tenant = true
f.Storage = true
f.ComputeInstance = true
f.Cluster = true
f.Networking = true
f.BareMetalInstance = true
setupLog.Info("no controller flags set, enabling all controllers")
setupLog.Info("no controller flags set, enabling all controllers except volume (no vendor provisioner configured)")
}
}

Expand Down Expand Up @@ -473,6 +485,80 @@ func setupStorageController(mgr mcmanager.Manager, grpcConn *grpc.ClientConn, ma
return nil
}

// setupControllers registers all enabled controllers with the manager.
func setupControllers(
mgr mcmanager.Manager, grpcConn *grpc.ClientConn,
flags *controllerFlags, maxJobHistory int,
) error {
if flags.Cluster {
if err := setupClusterControllers(mgr, grpcConn, maxJobHistory); err != nil {
return fmt.Errorf("cluster controllers: %w", err)
}
}
if flags.ComputeInstance {
if err := setupComputeInstanceControllers(mgr, grpcConn, maxJobHistory); err != nil {
return fmt.Errorf("computeinstance controllers: %w", err)
}
}
if flags.Tenant {
if err := setupTenantController(mgr); err != nil {
return fmt.Errorf("tenant controller: %w", err)
}
}
if flags.Storage {
if err := setupStorageController(mgr, grpcConn, maxJobHistory); err != nil {
return fmt.Errorf("storage controller: %w", err)
}
}
if flags.Volume {
if err := setupVolumeControllers(mgr, grpcConn); err != nil {
return fmt.Errorf("volume controllers: %w", err)
}
}
if flags.Networking {
if err := setupNetworkingControllers(mgr, grpcConn, maxJobHistory); err != nil {
return fmt.Errorf("networking controllers: %w", err)
}
}
if flags.BareMetalInstance {
if err := setupBareMetalInstanceControllers(mgr, grpcConn); err != nil {
return fmt.Errorf("baremetalinstance controllers: %w", err)
}
}
return nil
}

// setupVolumeControllers registers the Volume resource controller and, when
// grpcConn is set, the Volume feedback controller. The Volume controller uses
// a VendorProvisioner interface instead of AAP; for now no real vendor is
// configured (nil provisioner), so the controller sets Progressing and waits
// for the vendor CSI integration in a follow-up PR.
func setupVolumeControllers(mgr mcmanager.Manager, grpcConn *grpc.ClientConn) error {
localMgr := mgr.GetLocalManager()
volumeNamespace := os.Getenv(envVolumeNamespace)

if grpcConn != nil {
if err := controller.NewVolumeFeedbackReconciler(
localMgr.GetClient(),
grpcConn,
volumeNamespace,
).SetupWithManager(mgr); err != nil {
return fmt.Errorf("volume feedback controller: %w", err)
}
}

// VendorProvisioner is nil until the real vendor CSI client is wired.
// The controller will set phase to Progressing and skip provisioning.
if err := controller.NewVolumeReconciler(
mgr,
volumeNamespace,
nil,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
).SetupWithManager(mgr); err != nil {
return fmt.Errorf("volume controller: %w", err)
}
return nil
}

// setupNetworkingControllers registers all networking controllers along with their
// feedback controllers when grpcConn is set.
func setupNetworkingControllers(
Expand Down Expand Up @@ -976,41 +1062,9 @@ func main() {
})
setupLog.Info("job history configuration", "maxJobs", maxJobHistory)

if ctrlFlags.Cluster {
if err := setupClusterControllers(mgr, grpcConn, maxJobHistory); err != nil {
setupLog.Error(err, "unable to setup cluster controllers")
os.Exit(1)
}
}
if ctrlFlags.ComputeInstance {
if err := setupComputeInstanceControllers(mgr, grpcConn, maxJobHistory); err != nil {
setupLog.Error(err, "unable to setup computeinstance controllers")
os.Exit(1)
}
}
if ctrlFlags.Tenant {
if err := setupTenantController(mgr); err != nil {
setupLog.Error(err, "unable to setup tenant controller")
os.Exit(1)
}
}
if ctrlFlags.Storage {
if err := setupStorageController(mgr, grpcConn, maxJobHistory); err != nil {
setupLog.Error(err, "unable to setup storage controller")
os.Exit(1)
}
}
if ctrlFlags.Networking {
if err := setupNetworkingControllers(mgr, grpcConn, maxJobHistory); err != nil {
setupLog.Error(err, "unable to setup networking controllers")
os.Exit(1)
}
}
if ctrlFlags.BareMetalInstance {
if err := setupBareMetalInstanceControllers(mgr, grpcConn); err != nil {
setupLog.Error(err, "unable to setup baremetalinstance controllers")
os.Exit(1)
}
if err := setupControllers(mgr, grpcConn, ctrlFlags, maxJobHistory); err != nil {
setupLog.Error(err, "unable to setup controllers")
os.Exit(1)
}

// +kubebuilder:scaffold:builder
Expand Down
3 changes: 3 additions & 0 deletions osac-operator/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ rules:
- subnets/finalizers
- tenants/finalizers
- virtualnetworks/finalizers
- volumes/finalizers
verbs:
- update
- apiGroups:
Expand All @@ -134,6 +135,7 @@ rules:
- subnets
- tenants
- virtualnetworks
- volumes
verbs:
- create
- delete
Expand All @@ -155,6 +157,7 @@ rules:
- subnets/status
- tenants/status
- virtualnetworks/status
- volumes/status
verbs:
- get
- patch
Expand Down
Loading
Loading