Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ spec:
description: >-
cloudCredentialsRef points to a Kubernetes Secret containing
an OpenStack clouds.yaml file. The operator reads this secret
directly at reconcile time no volume mount is required.
directly at reconcile time; no volume mount is required.
type: object
required:
- secretName
Expand Down Expand Up @@ -85,7 +85,9 @@ spec:
maxLength: 255
pattern: ^[A-Za-z0-9._-]+$
service_type:
description: Neutron service type for the flavor.
description: >-
Neutron service type for the flavor. For router flavors this
is always L3_ROUTER_NAT (plugin_constants.L3 in neutron-lib).
type: string
enum:
- L3_ROUTER_NAT
Expand Down Expand Up @@ -117,7 +119,7 @@ spec:
type: string
format: uuid
meta_info:
description: Service profile metainfo payload.
description: Service profile metadata payload.
type: object
properties:
resource_class:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Example values override for a future plugin that needs Kubernetes resources
# outside the chart-generated defaults.
#
# Use with:
# helm template openstack-sync-operator ../ -f extra-rbac-rules-values.yaml
#
# Default RBAC
# ------------
# Without rbac.rules, the chart generates the permissions it can infer:
#
# 1. Secret read access, always:
# apiGroups: [""]
# resources: ["secrets"]
# verbs: ["get"]
#
# 2. For each enabled plugin, CRD read/watch access from pluginData.<name>.hook.crd:
# verbs: ["get", "list", "watch"]
#
# 3. For each enabled plugin whose CRD defines a status subresource:
# resources: ["<plural>/status"]
# verbs: ["get", "patch", "update"]
#
# For example, enabling plugins.neutronRouterFlavors adds access to:
# - neutronrouterflavors
# - neutronrouterflavors/status
#
# Extra RBAC
# ----------
# rbac.rules is only for resources the chart cannot infer from plugin CRDs.
# Each item is appended verbatim to the generated Role or ClusterRole.
#
# When rbac.clusterWide is false, these rules go into a namespaced Role.
# When rbac.clusterWide is true, these rules go into a ClusterRole.

rbac:
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
16 changes: 8 additions & 8 deletions components/openstack-sync-operator/templates/_crd.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ Read hook CRD metadata used by RBAC and shell-operator environment wiring.
{{- $hook := index . 2 -}}
{{- $crdPath := get $hook "crd" -}}
{{- if not $crdPath -}}
{{- fail (printf "hooks.%s.crd is required for CRD metadata" $hookName) -}}
{{- fail (printf "pluginData.%s.hook.crd is required for CRD metadata" $hookName) -}}
{{- end -}}
{{- $crdYaml := required (printf "hooks.%s.crd file %s is empty or missing" $hookName $crdPath) ($root.Files.Get $crdPath) -}}
{{- $crdYaml := required (printf "pluginData.%s.hook.crd file %s is empty or missing" $hookName $crdPath) ($root.Files.Get $crdPath) -}}
{{- $crd := fromYaml $crdYaml -}}
{{- if ne $crd.kind "CustomResourceDefinition" -}}
{{- fail (printf "hooks.%s.crd must point to a CustomResourceDefinition" $hookName) -}}
{{- fail (printf "pluginData.%s.hook.crd must point to a CustomResourceDefinition" $hookName) -}}
{{- end -}}
{{- $group := required (printf "hooks.%s.crd spec.group is required" $hookName) $crd.spec.group -}}
{{- $kind := required (printf "hooks.%s.crd spec.names.kind is required" $hookName) $crd.spec.names.kind -}}
{{- $plural := required (printf "hooks.%s.crd spec.names.plural is required" $hookName) $crd.spec.names.plural -}}
{{- $group := required (printf "pluginData.%s.hook.crd spec.group is required" $hookName) $crd.spec.group -}}
{{- $kind := required (printf "pluginData.%s.hook.crd spec.names.kind is required" $hookName) $crd.spec.names.kind -}}
{{- $plural := required (printf "pluginData.%s.hook.crd spec.names.plural is required" $hookName) $crd.spec.names.plural -}}
{{- $storageVersion := "" -}}
{{- $hasStatus := false -}}
{{- range $version := required (printf "hooks.%s.crd spec.versions is required" $hookName) $crd.spec.versions }}
{{- range $version := required (printf "pluginData.%s.hook.crd spec.versions is required" $hookName) $crd.spec.versions }}
{{- if $version.storage -}}
{{- $storageVersion = $version.name -}}
{{- end -}}
Expand All @@ -28,7 +28,7 @@ Read hook CRD metadata used by RBAC and shell-operator environment wiring.
{{- end -}}
{{- end -}}
{{- if not $storageVersion -}}
{{- fail (printf "hooks.%s.crd must define a storage version" $hookName) -}}
{{- fail (printf "pluginData.%s.hook.crd must define a storage version" $hookName) -}}
{{- end -}}
{{- dict
"apiVersion" (printf "%s/%s" $group $storageVersion)
Expand Down
5 changes: 1 addition & 4 deletions components/openstack-sync-operator/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ required because shell-operator reads hook watches only when the pod starts.
{{- end }}

{{/*
Normalize built-in plugin hooks and direct hook definitions.
Normalize built-in plugin hooks.
*/}}
{{- define "openstack-sync-operator.configuredHooks" -}}
{{- $hooks := dict -}}
Expand All @@ -91,8 +91,5 @@ Normalize built-in plugin hooks and direct hook definitions.
{{- $_2 := set $hooks $pluginName $hookValues -}}
{{- end -}}
{{- end -}}
{{- range $hookName, $hook := default dict .Values.hooks -}}
{{- $_ := set $hooks $hookName $hook -}}
{{- end -}}
{{- $hooks | toYaml -}}
{{- end }}
13 changes: 12 additions & 1 deletion components/openstack-sync-operator/templates/deployment.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
{{- end }}
{{- end }}
{{- end -}}
{{- $operatorEnv := dict "LOG_LEVEL" "info" -}}
{{- range $envName, $envValue := default dict .Values.env }}
{{- if hasKey $hookEnv $envName }}
{{- fail (printf "duplicate operator environment variable %s" $envName) }}
{{- end }}
{{- $_ = set $operatorEnv $envName $envValue -}}
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
Expand Down Expand Up @@ -65,7 +72,7 @@ spec:
- |
missing=0
{{- range $hookName, $hook := $enabledHooks }}
{{- $hookPath := required (printf "hooks.%s.path is required when hook is enabled" $hookName) $hook.path }}
{{- $hookPath := required (printf "pluginData.%s.hook.path is required when hook is enabled" $hookName) $hook.path }}
if [ ! -x {{ $hookPath | quote }} ]; then
echo {{ printf "enabled hook %s missing or not executable: %s" $hookName $hookPath | quote }} >&2
missing=1
Expand Down Expand Up @@ -104,6 +111,10 @@ spec:
- name: {{ $envName }}
value: {{ get $hookEnv $envName | quote }}
{{- end }}
{{- range $envName := keys $operatorEnv | sortAlpha }}
- name: {{ $envName }}
value: {{ get $operatorEnv $envName | quote }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
Expand Down
86 changes: 60 additions & 26 deletions components/openstack-sync-operator/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
"type": "object",
"additionalProperties": true,
"properties": {
"hooks": {
"type": "object",
"description": "Additional hook definitions keyed by hook name.",
"additionalProperties": {
"$ref": "#/definitions/hook"
}
"env": {
"description": "Operator-level environment variables injected directly into the container.",
"$ref": "#/definitions/operatorEnv"
},
"plugins": {
"type": "object",
Expand All @@ -21,24 +18,44 @@
"type": "object",
"description": "Built-in plugin hook data keyed by plugin name.",
"additionalProperties": {
"type": "object",
"additionalProperties": true,
"properties": {
"hook": {
"$ref": "#/definitions/hook"
}
}
"$ref": "#/definitions/pluginData"
}
}
},
"definitions": {
"hook": {
"operatorEnv": {
"type": "object",
"propertyNames": {
"pattern": "^[A-Z][A-Z0-9_]*$"
},
"properties": {
"LOG_LEVEL": {
"type": "string",
"default": "info",
"enum": [
"debug",
"info",
"error"
]
}
},
"additionalProperties": {
"$ref": "#/definitions/envValue"
}
},
"pluginData": {
"type": "object",
"additionalProperties": false,
"properties": {
"hook": {
"$ref": "#/definitions/pluginHook"
}
}
},
"pluginHook": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"path": {
"type": "string",
"minLength": 1
Expand All @@ -53,17 +70,34 @@
"pattern": "^[A-Z][A-Z0-9_]*$"
},
"env": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"number",
"integer",
"boolean"
]
}
"$ref": "#/definitions/hookEnv"
}
}
},
"hookEnv": {
"type": "object",
"propertyNames": {
"pattern": "^[A-Z][A-Z0-9_]*$"
},
"additionalProperties": {
"$ref": "#/definitions/envValue"
}
},
"envValue": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number"
},
{
"type": "string",
"not": {
"pattern": "^\\s*([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|1|0|[Yy][Ee][Ss]|[Nn][Oo]|[Oo][Nn]|[Oo][Ff][Ff])\\s*$"
}
}
]
}
}
}
27 changes: 8 additions & 19 deletions components/openstack-sync-operator/values.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
replicaCount: 1

# Operator-level environment variables injected directly into the container.
# LOG_LEVEL controls both shell-operator and Python hook logging.
env:
LOG_LEVEL: info

image:
repository: ghcr.io/rackerlabs/understack/openstack-sync-operator
pullPolicy: IfNotPresent
Expand All @@ -13,12 +18,7 @@ serviceAccount:
rbac:
create: true
clusterWide: false
# The base placeholder hook has no Kubernetes bindings. Add hook permissions
# here with the hook that needs them.
rules: []

# Built-in plugin enablement. Site values normally only override these booleans
# and selected pluginData.<name>.hook.env values.
# Built-in hook configuration. Site values normally override only:
# - plugins.<name>: enable or disable a hook
# - pluginData.<name>.hook.env: override selected hook env values
Expand Down Expand Up @@ -48,17 +48,6 @@ pluginData:
envPrefix: NEUTRON_ROUTER_FLAVOR
env:
SYNC_CRONTAB: "0 * * * *"
PRUNE: "false"
DEFAULT_SECRET: infrasetup
DEFAULT_CLOUD: understack

hooks: {}

podAnnotations: {}
podLabels: {}

resources: {}

nodeSelector: {}
tolerations: []
affinity: {}
# When true, removing a NeutronRouterFlavor CR also deletes its unused
# operator-managed OpenStack flavor. Enable this before removing the CR.
PRUNE: false
6 changes: 4 additions & 2 deletions python/openstack-sync/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

Shell-operator package for OpenStack reconciliation hooks.

The base image ships with a no-op placeholder hook. Resource-specific sync hooks
are added as plugins.
The operator image ships with a no-op placeholder hook and resource-specific
sync hooks under `openstack_sync/hooks/`. The Neutron router flavor hook is
implemented under `openstack_sync/plugins/neutron/router_flavors/` and exposed
to shell-operator as `/hooks/router_flavors.py`.
Loading
Loading