Skip to content

SUNET/openstack-operator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenStack Operator

A Kopf-based Kubernetes operator for declaratively managing OpenStack resources, including:

Cluster-scoped resources:

  • Domains (Keystone)
  • Flavors (Nova)
  • Images (Glance) with web-download support
  • Provider networks (Neutron)

Namespace-scoped resources:

  • Projects and user groups
  • Quotas (compute, storage, network)
  • Networks, subnets, and routers
  • Security groups and rules
  • Role bindings
  • Federation mappings for SSO access

CRDs

OpenstackDomain (cluster-scoped)

Manages Keystone domains for organizing users and projects.

apiVersion: sunet.se/v1alpha1
kind: OpenstackDomain
metadata:
  name: sso-users
spec:
  name: sso-users
  description: "Domain for SSO-authenticated users"
  enabled: true

Status:

status:
  phase: Ready
  domainId: "abc123..."
  conditions:
    - type: Ready
      status: "True"

OpenstackFlavor (cluster-scoped)

Manages Nova flavors for VM sizing.

apiVersion: sunet.se/v1alpha1
kind: OpenstackFlavor
metadata:
  name: b2.c2r4
spec:
  name: b2.c2r4
  vcpus: 2
  ram: 4096      # MB
  disk: 0        # GB (0 = boot from volume)
  ephemeral: 0   # GB
  swap: 0        # MB
  isPublic: true
  extraSpecs:
    "hw:cpu_policy": "shared"

Status:

status:
  phase: Ready
  flavorId: "def456..."
  conditions:
    - type: Ready
      status: "True"

OpenstackImage (cluster-scoped)

Manages Glance images with support for web-download import.

apiVersion: sunet.se/v1alpha1
kind: OpenstackImage
metadata:
  name: debian-13
spec:
  name: "Debian 13 (Trixie)"
  visibility: public
  protected: false
  tags:
    - debian
    - trixie
  properties:
    os_distro: debian
    os_version: "13"
  content:
    diskFormat: qcow2
    containerFormat: bare
    source:
      url: https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-generic-amd64-daily.qcow2

Status:

status:
  phase: Ready
  imageId: "ghi789..."
  uploadStatus: active
  checksum: "abc123..."
  sizeBytes: 1234567890
  conditions:
    - type: Ready
      status: "True"

OpenstackNetwork (cluster-scoped)

Manages provider networks (external/flat networks).

apiVersion: sunet.se/v1alpha1
kind: OpenstackNetwork
metadata:
  name: external
spec:
  name: external
  external: true
  shared: false
  providerNetworkType: flat
  providerPhysicalNetwork: external
  subnets:
    - name: external-subnet
      cidr: 192.168.1.0/24
      gateway: 192.168.1.1
      enableDhcp: false
      allocationPools:
        - start: 192.168.1.100
          end: 192.168.1.200

Status:

status:
  phase: Ready
  networkId: "jkl012..."
  subnets:
    - name: external-subnet
      subnetId: "mno345..."
  conditions:
    - type: Ready
      status: "True"

OpenstackProject (namespace-scoped)

Manages projects with full resource provisioning.

apiVersion: sunet.se/v1alpha1
kind: OpenstackProject
metadata:
  name: my-project
spec:
  name: "my-project.example.com"
  description: "My OpenStack project"
  domain: "sso-users"
  enabled: true

  quotas:
    compute:
      instances: 20
      cores: 40
      ramMB: 81920
    storage:
      volumes: 20
      volumesGB: 1000
    network:
      floatingIps: 10

  networks:
    - name: internal
      cidr: 192.168.100.0/24
      enableDhcp: true
      router:
        externalNetwork: external
        enableSnat: true

  securityGroups:
    - name: allow-ssh
      rules:
        - direction: ingress
          protocol: tcp
          portRangeMin: 22
          portRangeMax: 22
          remoteIpPrefix: "0.0.0.0/0"

  roleBindings:
    - role: member
      users:
        - [email protected]
        - [email protected]
      userDomain: sso-users

  federationRef:
    configMapName: federation-config

Status:

status:
  phase: Ready
  projectId: "abc123..."
  groupId: "def456..."
  networks:
    - name: internal
      networkId: "..."
      subnetId: "..."
      routerId: "..."
  securityGroups:
    - name: allow-ssh
      id: "..."
  conditions:
    - type: ProjectReady
      status: "True"
    - type: NetworksReady
      status: "True"

Building

# Build Docker image
docker build -t docker.sunet.se/platform/openstack-operator:latest .

# Or use Jenkins (see .jenkins.yaml)

Deployment

The operator requires:

  1. OpenStack credentials - A Secret with clouds.yaml containing admin credentials
  2. CRDs installed - All CRDs from crds/
  3. RBAC configured - ServiceAccount with cluster-wide access to the CRDs

Example deployment using kustomize:

# From a deployment overlay
kubectl apply -k overlays/test/

Development

# Install dependencies
pip install -e ".[dev]"

# Run locally (requires kubeconfig and OpenStack credentials)
export OS_CLOUD=openstack
export OS_CLIENT_CONFIG_FILE=/path/to/clouds.yaml
kopf run src/handlers.py --standalone

# Run tests
pytest

Configuration

Environment Variables

Variable Description Default
OS_CLOUD Cloud name in clouds.yaml openstack
OS_CLIENT_CONFIG_FILE Path to clouds.yaml Standard locations
WATCH_NAMESPACE Namespace to watch (empty = all) ""

Federation ConfigMap

For SSO integration, create a ConfigMap with IdP settings:

apiVersion: v1
kind: ConfigMap
metadata:
  name: federation-config
data:
  idp-name: satosa
  idp-remote-id: https://idp.example.com
  sso-domain: sso-users

Reference it in OpenstackProject via federationRef.

Resource Lifecycle

Cluster-scoped Resources

  • Domains: Created/updated on spec changes. Disabled before deletion.
  • Flavors: Immutable after creation. Spec changes require delete+recreate.
  • Images: Created with metadata, then web-download import triggered. Status polled until active.
  • Networks: Provider networks with subnets. Subnets deleted before network on removal.

Project Resources

  • Projects: Created with associated user group. Quotas applied after creation.
  • Networks: Project networks with optional router to external network.
  • Security Groups: Created with rules. Default egress rules added automatically.
  • Federation: Mapping created for SSO group-to-project binding.

Garbage Collection

The operator tracks all managed resources in a ConfigMap (openstack-operator-managed-resources). Orphaned resources (those without corresponding CRs) are automatically cleaned up.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published