Add zuul-registry deployment
This change adds an optional registry configuration to the spec: registry: image: docker.io/zuul/zuul-registry:latest count: 0 storage-size: 20 public-url: https://registry:9000 The operator expect a {{ cr_name }}-registry-tls secret to be provided for tls and user configuration. If the secret is missing, the operator creates self signed certificates and generates the user password. Depends-On: https://review.opendev.org/710644 Change-Id: I0c054485b0ad01d53ddcff93f7bcbf34d1810325
This commit is contained in:
parent
4a12041754
commit
c6d35be4d6
@ -28,6 +28,7 @@
|
||||
allowed-projects: zuul/zuul-operator
|
||||
requires:
|
||||
- zuul-container-image
|
||||
- zuul-registry-container-image
|
||||
- nodepool-container-image
|
||||
provides:
|
||||
- zuul-operator-container-image
|
||||
|
@ -83,6 +83,20 @@ let Schemas =
|
||||
}
|
||||
, default = { image = None Text, count = None Natural }
|
||||
}
|
||||
, Registry =
|
||||
{ Type =
|
||||
{ image : Optional Text
|
||||
, count : Optional Natural
|
||||
, storage-size : Optional Natural
|
||||
, public-url : Optional Text
|
||||
}
|
||||
, default =
|
||||
{ image = None Text
|
||||
, count = None Natural
|
||||
, storage-size = None Natural
|
||||
, public-url = None Text
|
||||
}
|
||||
}
|
||||
, Launcher =
|
||||
{ Type = { image : Optional Text, config : UserSecret }
|
||||
, default.image = None Text
|
||||
@ -128,6 +142,7 @@ let Input =
|
||||
, executor : Schemas.Executor.Type
|
||||
, web : Schemas.Web.Type
|
||||
, scheduler : Schemas.Scheduler.Type
|
||||
, registry : Schemas.Registry.Type
|
||||
, launcher : Schemas.Launcher.Type
|
||||
, database : Optional UserSecret
|
||||
, zookeeper : Optional UserSecret
|
||||
@ -142,6 +157,7 @@ let Input =
|
||||
, merger = Schemas.Merger.default
|
||||
, web = Schemas.Web.default
|
||||
, scheduler = Schemas.Scheduler.default
|
||||
, registry = Schemas.Registry.default
|
||||
, executor = Schemas.Executor.default
|
||||
, launcher = Schemas.Launcher.default
|
||||
, connections = Schemas.Connections.default
|
||||
|
@ -12,6 +12,14 @@ The resources expect secrets to be created by the zuul ansible role:
|
||||
* `client.pem`
|
||||
* `client.key`
|
||||
|
||||
* `${name}-registry-tls` with:
|
||||
|
||||
* `cert.pem`
|
||||
* `cert.key`
|
||||
* `secret` a password
|
||||
* `username` the user name with write access
|
||||
* `password` the user password
|
||||
|
||||
* `${name}-database-password` with a `password` key, (unless an input.database db uri is provided).
|
||||
-}
|
||||
let Prelude = ../Prelude.dhall
|
||||
@ -72,6 +80,11 @@ let {- The Kubernetes resources of a Component
|
||||
}
|
||||
}
|
||||
|
||||
let DefaultNat =
|
||||
\(value : Optional Natural)
|
||||
-> \(default : Natural)
|
||||
-> merge { None = default, Some = \(some : Natural) -> some } value
|
||||
|
||||
let DefaultText =
|
||||
\(value : Optional Text)
|
||||
-> \(default : Text)
|
||||
@ -568,6 +581,38 @@ in \(input : Input)
|
||||
[ { path = "zuul.conf", content = mkZuulConf input zk-hosts } ]
|
||||
}
|
||||
|
||||
let etc-zuul-registry =
|
||||
Volume::{
|
||||
, name = input.name ++ "-secret-registry"
|
||||
, dir = "/etc/zuul"
|
||||
, files =
|
||||
[ { path = "registry.yaml"
|
||||
, content =
|
||||
let public-url =
|
||||
DefaultText
|
||||
input.registry.public-url
|
||||
"https://registry:9000"
|
||||
|
||||
in ''
|
||||
registry:
|
||||
address: '0.0.0.0'
|
||||
port: 9000
|
||||
public-url: ${public-url}
|
||||
tls-cert: /etc/zuul-registry/cert.pem
|
||||
tls-key: /etc/zuul-registry/cert.key
|
||||
secret: "%(ZUUL_REGISTRY_secret)"
|
||||
storage:
|
||||
driver: filesystem
|
||||
root: /var/lib/zuul
|
||||
users:
|
||||
- name: "%(ZUUL_REGISTRY_username)"
|
||||
pass: "%(ZUUL_REGISTRY_password)"
|
||||
access: write
|
||||
''
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let etc-nodepool =
|
||||
Volume::{
|
||||
, name = input.name ++ "-secret-nodepool"
|
||||
@ -876,6 +921,72 @@ in \(input : Input)
|
||||
}
|
||||
)
|
||||
}
|
||||
, Registry =
|
||||
let registry-volumes =
|
||||
[ etc-zuul-registry
|
||||
, Volume::{
|
||||
, name = input.name ++ "-registry-tls"
|
||||
, dir = "/etc/zuul-registry"
|
||||
}
|
||||
]
|
||||
|
||||
let registry-env =
|
||||
mkEnvVarSecret
|
||||
( Prelude.List.map
|
||||
Text
|
||||
EnvSecret
|
||||
( \(key : Text)
|
||||
-> { name = "ZUUL_REGISTRY_${key}"
|
||||
, key = key
|
||||
, secret =
|
||||
input.name ++ "-registry-tls"
|
||||
}
|
||||
)
|
||||
[ "secret", "username", "password" ]
|
||||
)
|
||||
|
||||
in KubernetesComponent::{
|
||||
, Service = Some
|
||||
(mkService "registry" "registry" 9000)
|
||||
, StatefulSet = Some
|
||||
( mkStatefulSet
|
||||
Component::{
|
||||
, name = "registry"
|
||||
, count =
|
||||
DefaultNat input.registry.count 0
|
||||
, data-dir = zuul-data-dir
|
||||
, volumes = registry-volumes
|
||||
, claim-size =
|
||||
DefaultNat
|
||||
input.registry.storage-size
|
||||
20
|
||||
, container = Kubernetes.Container::{
|
||||
, name = "registry"
|
||||
, image = zuul-image "registry"
|
||||
, args = Some
|
||||
[ "zuul-registry"
|
||||
, "-c"
|
||||
, "/etc/zuul/registry.yaml"
|
||||
, "serve"
|
||||
]
|
||||
, imagePullPolicy = Some "IfNotPresent"
|
||||
, ports = Some
|
||||
[ Kubernetes.ContainerPort::{
|
||||
, name = Some "registry"
|
||||
, containerPort = 9000
|
||||
}
|
||||
]
|
||||
, env = Some registry-env
|
||||
, volumeMounts = Some
|
||||
( mkVolumeMount
|
||||
( registry-volumes
|
||||
# zuul-data-dir
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
, Nodepool =
|
||||
let nodepool-image =
|
||||
@ -1008,13 +1119,17 @@ in \(input : Input)
|
||||
{ apiVersion = "v1"
|
||||
, kind = "List"
|
||||
, items =
|
||||
[ mkSecret etc-zuul, mkSecret etc-nodepool ]
|
||||
[ mkSecret etc-zuul
|
||||
, mkSecret etc-nodepool
|
||||
, mkSecret etc-zuul-registry
|
||||
]
|
||||
# mkUnion Components.Backend.Database
|
||||
# mkUnion Components.Backend.ZooKeeper
|
||||
# mkUnion Components.Zuul.Scheduler
|
||||
# mkUnion Components.Zuul.Executor
|
||||
# mkUnion Components.Zuul.Web
|
||||
# mkUnion Components.Zuul.Merger
|
||||
# mkUnion Components.Zuul.Registry
|
||||
# mkUnion Components.Nodepool.Launcher
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ spec:
|
||||
scheduler:
|
||||
config:
|
||||
secretName: zuul-yaml-conf
|
||||
registry:
|
||||
count: 1
|
||||
launcher:
|
||||
config:
|
||||
secretName: nodepool-yaml-conf
|
||||
|
@ -13,6 +13,8 @@ merger:
|
||||
scheduler:
|
||||
config:
|
||||
secretName: zuul-yaml-conf
|
||||
registry:
|
||||
count: 0
|
||||
launcher:
|
||||
config:
|
||||
secretName: nodepool-yaml-conf
|
||||
|
@ -5,6 +5,7 @@
|
||||
command: python3 -m pip install --user openshift
|
||||
roles:
|
||||
- role: clear-firewall
|
||||
- role: install-podman
|
||||
- role: install-kubernetes
|
||||
vars:
|
||||
minikube_dns_resolvers:
|
||||
|
@ -132,6 +132,8 @@
|
||||
kubernetes:
|
||||
secretName: nodepool-kube-config
|
||||
key: kube.config
|
||||
registry:
|
||||
count: 1
|
||||
|
||||
- name: Wait maximum 4 minutes for the scheduler deployment
|
||||
shell: |
|
||||
@ -164,3 +166,27 @@
|
||||
- name: Wait an extra 2 minutes for the services to settle
|
||||
pause:
|
||||
minutes: 2
|
||||
|
||||
- name: Test the registry
|
||||
block:
|
||||
- name: Get registry service ip
|
||||
command: kubectl get svc registry -o "jsonpath={.spec.clusterIP}"
|
||||
register: _registry_ip
|
||||
|
||||
- name: Add registry to /etc/hosts
|
||||
become: yes
|
||||
lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: "^.* registry$"
|
||||
line: "{{ _registry_ip.stdout_lines[0] }} registry"
|
||||
|
||||
- name: Get registry password
|
||||
command: kubectl get secret zuul-registry-tls -o "jsonpath={.data.password}"
|
||||
register: _registry_password
|
||||
|
||||
- name: Test registry login
|
||||
command: >
|
||||
podman login
|
||||
--tls-verify=false registry:9000
|
||||
-u zuul
|
||||
-p "{{ _registry_password.stdout_lines[0] | b64decode }}"
|
||||
|
29
roles/zuul-ensure-registry-tls/tasks/main.yaml
Normal file
29
roles/zuul-ensure-registry-tls/tasks/main.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
- name: Check if registry tls cert exists
|
||||
set_fact:
|
||||
registry_certs: "{{ lookup('k8s', api_version='v1', kind='Secret', namespace=namespace, resource_name=zuul_name + '-registry-tls') }}"
|
||||
|
||||
- name: Generate and store certs
|
||||
when: registry_certs.data is not defined
|
||||
block:
|
||||
- name: Generate certs
|
||||
command: "{{ item }}"
|
||||
loop:
|
||||
# Server
|
||||
- "openssl req -new -newkey rsa:2048 -nodes -keyout registry-{{ zuul_name }}.key -out registry-{{ zuul_name }}.csr -subj '/C=US/ST=Texas/L=Austin/O=Zuul/CN=server-{{ zuul_name }}'"
|
||||
- "openssl x509 -req -days 3650 -in registry-{{ zuul_name }}.csr -out registry-{{ zuul_name }}.pem -CA ca-{{ zuul_name }}.pem -CAkey ca-{{ zuul_name }}.key -CAcreateserial"
|
||||
|
||||
- name: Create k8s secret
|
||||
k8s:
|
||||
state: "{{ state }}"
|
||||
namespace: "{{ namespace }}"
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ zuul_name }}-registry-tls"
|
||||
stringData:
|
||||
username: "zuul"
|
||||
password: "{{ lookup('password', '/dev/null') }}"
|
||||
secret: "{{ lookup('password', '/dev/null') }}"
|
||||
cert.key: "{{ lookup('file', 'registry-' + zuul_name + '.key') }}"
|
||||
cert.pem: "{{ lookup('file', 'registry-' + zuul_name + '.pem') }}"
|
@ -10,4 +10,5 @@ raw_spec: "{{ vars['_operator_zuul-ci_org_zuul_spec'] | default(spec) }}"
|
||||
# Provide sensible default for non optional attributes:
|
||||
spec_defaults:
|
||||
web: {}
|
||||
registry: {}
|
||||
externalConfig: {}
|
||||
|
@ -4,6 +4,10 @@
|
||||
- zuul-lookup-conf
|
||||
- zuul-ensure-gearman-tls
|
||||
|
||||
- include_role:
|
||||
name: zuul-ensure-registry-tls
|
||||
when: (raw_spec['registry']['count'] | default(0)) | int > 0
|
||||
|
||||
- include_role:
|
||||
name: zuul-ensure-database-password
|
||||
# when the user does not provide a db_uri
|
||||
|
Loading…
x
Reference in New Issue
Block a user