Skip to content

Instantly share code, notes, and snippets.

@spjmurray
Created October 30, 2024 14:32
Show Gist options
  • Save spjmurray/edc1d1036b5f4083a960143409092ad1 to your computer and use it in GitHub Desktop.
Save spjmurray/edc1d1036b5f4083a960143409092ad1 to your computer and use it in GitHub Desktop.
Region Security Groups Patch 1
commit 23771872a3ce515e80749c6dfc29da2043b60a78
Author: Simon Murray <[email protected]>
Date: Wed Oct 30 13:12:23 2024 +0000
Make This Usable
diff --git a/Makefile b/Makefile
index e518fdf..5b98ade 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,9 @@ REVISION := $(shell git rev-parse HEAD)
CONTROLLERS = \
unikorn-region-controller \
unikorn-identity-controller \
- unikorn-physical-network-controller
+ unikorn-physical-network-controller \
+ unikorn-security-group-controller \
+ unikorn-security-group-rule-controller
# Release will do cross compliation of all images for the 'all' target.
# Note we aren't fucking about with docker here because that opens up a
diff --git a/charts/region/templates/_helpers.tpl b/charts/region/templates/_helpers.tpl
index 3a9e961..bae55e7 100644
--- a/charts/region/templates/_helpers.tpl
+++ b/charts/region/templates/_helpers.tpl
@@ -13,6 +13,14 @@ Create the container images
{{- .Values.physicalNetworkController.image | default (printf "%s/unikorn-physical-network-controller:%s" (include "unikorn.defaultRepositoryPath" .) (.Values.tag | default .Chart.Version)) }}
{{- end }}
+{{- define "unikorn.securityGroupControllerImage" -}}
+{{- .Values.securityGroupController.image | default (printf "%s/unikorn-security-group-controller:%s" (include "unikorn.defaultRepositoryPath" .) (.Values.tag | default .Chart.Version)) }}
+{{- end }}
+
+{{- define "unikorn.securityGroupRuleControllerImage" -}}
+{{- .Values.securityGroupRuleController.image | default (printf "%s/unikorn-security-group-rule-controller:%s" (include "unikorn.defaultRepositoryPath" .) (.Values.tag | default .Chart.Version)) }}
+{{- end }}
+
{{/*
Create image pull secrets
*/}}
diff --git a/charts/region/templates/region-controller/clusterrole.yaml b/charts/region/templates/region-controller/clusterrole.yaml
index ff3e433..ea289ad 100644
--- a/charts/region/templates/region-controller/clusterrole.yaml
+++ b/charts/region/templates/region-controller/clusterrole.yaml
@@ -19,6 +19,8 @@ rules:
- identities
- physicalnetworks
- quotas
+ - securitygroups
+ - securitygrouprules
verbs:
- list
- watch
@@ -31,6 +33,8 @@ rules:
resources:
- openstackidentities
- openstackphysicalnetworks
+ - openstacksecuritygroups
+ - openstacksecuritygrouprules
verbs:
- list
- watch
diff --git a/charts/region/templates/security-group-controller/clusterrole.yaml b/charts/region/templates/security-group-controller/clusterrole.yaml
new file mode 100644
index 0000000..29066b0
--- /dev/null
+++ b/charts/region/templates/security-group-controller/clusterrole.yaml
@@ -0,0 +1,63 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+rules:
+# Orchestrate Unikorn resources (my job).
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - identities
+ - openstackidentities
+ verbs:
+ - list
+ - watch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - securitygroups
+ verbs:
+ - list
+ - watch
+ - update
+ - patch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - securitygroups/status
+ verbs:
+ - update
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - openstacksecuritygroups
+ verbs:
+ - list
+ - watch
+ - create
+ - update
+ - delete
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - securitygrouprules
+ verbs:
+ - list
+ - watch
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ verbs:
+ - list
+ - watch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - regions
+ verbs:
+ - list
+ - watch
diff --git a/charts/region/templates/security-group-controller/clusterrolebinding.yaml b/charts/region/templates/security-group-controller/clusterrolebinding.yaml
new file mode 100644
index 0000000..a35b2b5
--- /dev/null
+++ b/charts/region/templates/security-group-controller/clusterrolebinding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+subjects:
+- kind: ServiceAccount
+ namespace: {{ .Release.Namespace }}
+ name: unikorn-security-group-controller
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: unikorn-security-group-controller
diff --git a/charts/region/templates/security-group-controller/deployment.yaml b/charts/region/templates/security-group-controller/deployment.yaml
new file mode 100644
index 0000000..f030579
--- /dev/null
+++ b/charts/region/templates/security-group-controller/deployment.yaml
@@ -0,0 +1,41 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: unikorn-security-group-controller
+ template:
+ metadata:
+ labels:
+ app: unikorn-security-group-controller
+ spec:
+ containers:
+ - name: unikorn-security-group-controller
+ image: {{ include "unikorn.securityGroupControllerImage" . }}
+ args:
+ {{- include "unikorn.core.flags" . | nindent 8 }}
+ {{- include "unikorn.otlp.flags" . | nindent 8 }}
+ ports:
+ - name: http
+ containerPort: 6080
+ - name: prometheus
+ containerPort: 8080
+ - name: pprof
+ containerPort: 6060
+ resources:
+ requests:
+ cpu: "50m"
+ memory: 50Mi
+ limits:
+ cpu: "100m"
+ memory: 100Mi
+ securityContext:
+ readOnlyRootFilesystem: true
+ serviceAccountName: unikorn-security-group-controller
+ securityContext:
+ runAsNonRoot: true
diff --git a/charts/region/templates/security-group-controller/role.yaml b/charts/region/templates/security-group-controller/role.yaml
new file mode 100644
index 0000000..fbdec62
--- /dev/null
+++ b/charts/region/templates/security-group-controller/role.yaml
@@ -0,0 +1,23 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+rules:
+# Controller prerequisites.
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - create
+ - get
+ - update
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
diff --git a/charts/region/templates/security-group-controller/rolebinding.yaml b/charts/region/templates/security-group-controller/rolebinding.yaml
new file mode 100644
index 0000000..387bf9d
--- /dev/null
+++ b/charts/region/templates/security-group-controller/rolebinding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+subjects:
+- kind: ServiceAccount
+ namespace: {{ .Release.Namespace }}
+ name: unikorn-security-group-controller
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: unikorn-security-group-controller
diff --git a/charts/region/templates/security-group-controller/serviceaccount.yaml b/charts/region/templates/security-group-controller/serviceaccount.yaml
new file mode 100644
index 0000000..a2718e7
--- /dev/null
+++ b/charts/region/templates/security-group-controller/serviceaccount.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: unikorn-security-group-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+{{- with ( include "unikorn.imagePullSecrets" . ) }}
+imagePullSecrets:
+{{ . }}
+{{- end }}
diff --git a/charts/region/templates/security-group-rule-controller/clusterrole.yaml b/charts/region/templates/security-group-rule-controller/clusterrole.yaml
new file mode 100644
index 0000000..9a87e19
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/clusterrole.yaml
@@ -0,0 +1,57 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+rules:
+# Orchestrate Unikorn resources (my job).
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - identities
+ - openstackidentities
+ - securitygroups
+ - openstacksecuritygroups
+ verbs:
+ - list
+ - watch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - securitygrouprules
+ verbs:
+ - list
+ - watch
+ - update
+ - patch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - securitygrouprules/status
+ verbs:
+ - update
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - openstacksecuritygrouprules
+ verbs:
+ - list
+ - watch
+ - create
+ - update
+ - delete
+- apiGroups:
+ - ""
+ resources:
+ - secrets
+ verbs:
+ - list
+ - watch
+- apiGroups:
+ - region.unikorn-cloud.org
+ resources:
+ - regions
+ verbs:
+ - list
+ - watch
diff --git a/charts/region/templates/security-group-rule-controller/clusterrolebinding.yaml b/charts/region/templates/security-group-rule-controller/clusterrolebinding.yaml
new file mode 100644
index 0000000..666d7c3
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/clusterrolebinding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+subjects:
+- kind: ServiceAccount
+ namespace: {{ .Release.Namespace }}
+ name: unikorn-security-group-rule-controller
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: unikorn-security-group-rule-controller
diff --git a/charts/region/templates/security-group-rule-controller/deployment.yaml b/charts/region/templates/security-group-rule-controller/deployment.yaml
new file mode 100644
index 0000000..65aab77
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/deployment.yaml
@@ -0,0 +1,41 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: unikorn-security-group-rule-controller
+ template:
+ metadata:
+ labels:
+ app: unikorn-security-group-rule-controller
+ spec:
+ containers:
+ - name: unikorn-security-group-rule-controller
+ image: {{ include "unikorn.securityGroupRuleControllerImage" . }}
+ args:
+ {{- include "unikorn.core.flags" . | nindent 8 }}
+ {{- include "unikorn.otlp.flags" . | nindent 8 }}
+ ports:
+ - name: http
+ containerPort: 6080
+ - name: prometheus
+ containerPort: 8080
+ - name: pprof
+ containerPort: 6060
+ resources:
+ requests:
+ cpu: "50m"
+ memory: 50Mi
+ limits:
+ cpu: "100m"
+ memory: 100Mi
+ securityContext:
+ readOnlyRootFilesystem: true
+ serviceAccountName: unikorn-security-group-rule-controller
+ securityContext:
+ runAsNonRoot: true
diff --git a/charts/region/templates/security-group-rule-controller/role.yaml b/charts/region/templates/security-group-rule-controller/role.yaml
new file mode 100644
index 0000000..cf262d4
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/role.yaml
@@ -0,0 +1,23 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+rules:
+# Controller prerequisites.
+- apiGroups:
+ - coordination.k8s.io
+ resources:
+ - leases
+ verbs:
+ - create
+ - get
+ - update
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - update
diff --git a/charts/region/templates/security-group-rule-controller/rolebinding.yaml b/charts/region/templates/security-group-rule-controller/rolebinding.yaml
new file mode 100644
index 0000000..ee4e6f8
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/rolebinding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+subjects:
+- kind: ServiceAccount
+ namespace: {{ .Release.Namespace }}
+ name: unikorn-security-group-rule-controller
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: unikorn-security-group-rule-controller
diff --git a/charts/region/templates/security-group-rule-controller/serviceaccount.yaml b/charts/region/templates/security-group-rule-controller/serviceaccount.yaml
new file mode 100644
index 0000000..dfea428
--- /dev/null
+++ b/charts/region/templates/security-group-rule-controller/serviceaccount.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: unikorn-security-group-rule-controller
+ labels:
+ {{- include "unikorn.labels" . | nindent 4 }}
+{{- with ( include "unikorn.imagePullSecrets" . ) }}
+imagePullSecrets:
+{{ . }}
+{{- end }}
diff --git a/charts/region/values.yaml b/charts/region/values.yaml
index 918afcc..3edaf42 100644
--- a/charts/region/values.yaml
+++ b/charts/region/values.yaml
@@ -104,12 +104,20 @@ organization: unikorn-cloud
# Identity controller configuration.
identityController:
- # Allow override of the identity controller image.
- image:
+ # Allow override of the controller image.
+ image: ~
physicalNetworkController:
- # Allow override of the identity controller image.
- image:
+ # Allow override of the controller image.
+ image: ~
+
+securityGroupController:
+ # Allow override of the controller image.
+ image: ~
+
+securityGroupRuleController:
+ # Allow override of the controller image.
+ image: ~
# Sets the DNS hosts/X.509 Certs.
region:
diff --git a/docker/unikorn-security-group-controller/.dockerignore b/docker/unikorn-security-group-controller/.dockerignore
new file mode 100644
index 0000000..83d9b90
--- /dev/null
+++ b/docker/unikorn-security-group-controller/.dockerignore
@@ -0,0 +1,2 @@
+*
+!bin/*-linux-gnu/unikorn-security-group-controller
diff --git a/docker/unikorn-security-group-controller/Dockerfile b/docker/unikorn-security-group-controller/Dockerfile
new file mode 100644
index 0000000..d5bcfdc
--- /dev/null
+++ b/docker/unikorn-security-group-controller/Dockerfile
@@ -0,0 +1,8 @@
+FROM gcr.io/distroless/static:nonroot
+
+# This is implcitly created by 'docker buildx build'
+ARG TARGETARCH
+
+COPY bin/${TARGETARCH}-linux-gnu/unikorn-security-group-controller /
+
+ENTRYPOINT ["/unikorn-security-group-controller"]
diff --git a/docker/unikorn-security-group-rule-controller/.dockerignore b/docker/unikorn-security-group-rule-controller/.dockerignore
new file mode 100644
index 0000000..93d7c1d
--- /dev/null
+++ b/docker/unikorn-security-group-rule-controller/.dockerignore
@@ -0,0 +1,2 @@
+*
+!bin/*-linux-gnu/unikorn-security-group-rule-controller
diff --git a/docker/unikorn-security-group-rule-controller/Dockerfile b/docker/unikorn-security-group-rule-controller/Dockerfile
new file mode 100644
index 0000000..24eb181
--- /dev/null
+++ b/docker/unikorn-security-group-rule-controller/Dockerfile
@@ -0,0 +1,8 @@
+FROM gcr.io/distroless/static:nonroot
+
+# This is implcitly created by 'docker buildx build'
+ARG TARGETARCH
+
+COPY bin/${TARGETARCH}-linux-gnu/unikorn-security-group-rule-controller /
+
+ENTRYPOINT ["/unikorn-security-group-rule-controller"]
diff --git a/pkg/openapi/schema.go b/pkg/openapi/schema.go
index 52c2a35..4a926e1 100644
--- a/pkg/openapi/schema.go
+++ b/pkg/openapi/schema.go
@@ -19,126 +19,126 @@ import (
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
- "SXyIh4f/CQAA///1K4fHhL4AAA==",
+ "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",
+ "PIkP8fDwPwEAAP//UiRzCYu+AAA=",
}
// GetSwagger returns the content of the embedded swagger specification file
diff --git a/pkg/openapi/server.spec.yaml b/pkg/openapi/server.spec.yaml
index 4bc8d02..ad02e5b 100644
--- a/pkg/openapi/server.spec.yaml
+++ b/pkg/openapi/server.spec.yaml
@@ -1013,6 +1013,7 @@ components:
type: object
required:
- metadata
+ - spec
properties:
metadata:
$ref: 'https://raw.githubusercontent.com/unikorn-cloud/core/main/pkg/openapi/common.spec.yaml#/components/schemas/resourceWriteMetadata'
diff --git a/pkg/openapi/types.go b/pkg/openapi/types.go
index 4954dc0..9d40a5e 100644
--- a/pkg/openapi/types.go
+++ b/pkg/openapi/types.go
@@ -435,7 +435,7 @@ type SecurityGroupRuleWrite struct {
Metadata externalRef0.ResourceWriteMetadata `json:"metadata"`
// Spec A security group rule's specification.
- Spec *SecurityGroupRuleWriteSpec `json:"spec,omitempty"`
+ Spec SecurityGroupRuleWriteSpec `json:"spec"`
}
// SecurityGroupRuleWriteSpec A security group rule's specification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment