feat(infra): add uyuni role for configuration management

Added new ansible role `roles/uyuni/` to enable configuration and management of Uyuni satellite server infrastructure.
This commit is contained in:
mrwho 2026-07-19 14:41:22 +03:00
parent b32ea30345
commit b0a8b35dd9
23 changed files with 4120 additions and 0 deletions

View file

@ -0,0 +1,3 @@
/*.changes
/_*

View file

@ -0,0 +1,8 @@
apiVersion: v2
appVersion: "2026.06"
description: Uyuni server
home: https://www.uyuni-project.org/
icon: https://www.uyuni-project.org/img/uyuni-logo.svg
name: server-helm
type: application
version: 5.2.9

View file

@ -0,0 +1,309 @@
# server-helm
This chart installs [Uyuni server](https://uyuni-project.org).
This is deploying the core features, [the uyuni-charts repository](https://github.com/uyuni-project/uyuni-charts) contains some examples Helm charts using it in conjunction with other tools.
## Configuration
### Secrets
The following secrets with `kubernetes.io/basic-auth` type are required.
They need to contain a `username` and a `password` key.
- `db-admin-credentials`: PostgreSQL administrator credentials
- `db-credentials`: credentials for the internal database user
- `reportdb-credentials`: credentials for the report database user
- `admin-credentials`: credentials for the server administrator
SCC organization mirroring credentials can be automatically set if the name of secret of `kubernetes.io/basic-auth` type with those credentials is set as `server.sccSecret` value.
The following TLS secrets are expected:
- `db-cert`: is the TLS certificate for the report database and needs to have the `db` and `reportdb` Subject Alternate Names as well as the FQDN exposed to the outside world
- `uyuni-cert`: is the TLS certificate for the ingress rule and needs to have the public FQDN as Subject Alternate Name.
Pulling images from a registry requiring authentication requires a secret of `kubernetes.io/dockerconfigjson` type.
Its name needs to be passed as the `registrySecret` value.
### ConfigMaps
The Root CA certificate of `db-cert` and `uyuni-cert` are expected in ConfigMaps named `db-ca` and `uyuni-ca` with the certificate in the `ca.crt` key.
### Persistent Volumes
The following persistent volume claims will be created and will need to be bound to persistent volumes.
- `ca-certs`: (default size: 10Mi)
- `etc-apache2`: (default size: 1Mi)
- `etc-cobbler`: (default size: 1Mi)
- `etc-postfix`: (default size: 1Mi)
- `etc-rhn`: (default size: 1Mi)
- `etc-salt`: (default size: 1Mi)
- `etc-sssd`: (default size: 1Mi)
- `etc-sysconfig`: (default size: 20Mi)
- `etc-systemd-multi`: (default size: 1Mi)
- `etc-systemd-sockets`: (default size: 1Mi)
- `etc-tomcat`: (default size: 1Mi)
- `run-salt-master`: (default size: 10Mi)
- `srv-formulametadata`: (default size: 10Mi)
- `srv-pillar`: (default size: 10Mi)
- `srv-salt`: (default size: 10Mi)
- `srv-spacewalk`: (default size: 10Mi)
- `srv-susemanager`: (default size: 1Mi)
- `srv-tftpboot`: (default size: 300Mi)
- `srv-www`: (default size: 100Gi)
- `var-cache`: (default size: 10Gi)
- `var-cobbler`: (default size: 10Mi)
- `var-log`: (default size: 2Gi)
- `var-pgsql18`: (default size: 50Gi)
- `var-salt`: (default size: 10Mi)
- `var-search`: (default size: 10Gi)
- `var-spacewalk`: (default size: 100Gi)
They all are using the `ReadWriteOnce` access mode and can be configured in the values.
Changing the default volume sizes according to the distributions you plan to synchronize and manage is recommended.
See the [requirements documentation](https://www.uyuni-project.org/uyuni-docs/en/uyuni/installation-and-upgrade/uyuni-install-requirements.html) for more information.
The `volumes.storageClass` can be used to change the storage class of all the persistent volume claims.
This would be overridden by each claim's `volumes.<claim>.storageClass` value.
The storage class supports a special `"-"` value to force the storage class to the empty string.
This is different from the `""` value representing the default storage class by not setting any storage class at all.
Additional volumes can be attached to the server pod with `server.extraVolumes` and mounted into the server container with `server.extraVolumeMounts`.
This is useful for optional content volumes like `inter-server-sync` data without changing the chart templates.
For example:
```yaml
server:
extraVolumes:
- name: inter-server-sync-data
persistentVolumeClaim:
claimName: inter-server-sync-data
extraVolumeMounts:
- name: inter-server-sync-data
mountPath: /inter-server-sync-data
readOnly: true
```
### Node Tuning
For each of the components it is possible to tune the node where the pod will be scheduled.
This chart supports a **default** configuration with **local overrides**, allowing baseline rules to be set for all pods and customized for specific components when needed.
Scheduling can be controlled using `nodeSelector`, `affinity`, `tolerations`, or `nodeName`. It is not necessary to use all of them; simply choose the method that matches the cluster's scheduling strategy.
For example, to set a baseline rule for all components but override the placement for the `db` pod specifically, the `values.yaml` would look like this:
```yaml
# DEFAULTS
# These rules apply to all pods unless overridden by a specific component.
placement:
nodeSelector:
environment: production
tolerations:
- key: "server-tier"
operator: "Equal"
value: "true"
effect: "NoSchedule"
# LOCAL OVERRIDES
# These rules apply ONLY to the specific component and override the global equivalents.
db:
nodeSelector:
"kubernetes.io/hostname": "node-42"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/hostname"
operator: In
values:
- "node-42"
# nodeName: "node-42"
```
### Exposing ports
Uyuni requires some TCP and UDP ports to be routed to its services.
Here is a list of the ports to map:
| Protocol | Port | Service name | Service port | |
| -------- | ----- | ------------ | ------------ | ------------------------------------------------ |
| TCP | 5432 | reportdb | 5432 | |
| TCP | 4505 | salt | 4505 | |
| TCP | 4506 | salt | 4506 | |
| TCP | 8001 | taskomatic | 8001 | Only if installed with `exposeJavaDebug = true` |
| TCP | 8002 | search | 8002 | Only if installed with `exposeJavaDebug = true` |
| TCP | 8003 | tomcat | 8003 | Only if installed with `exposeJavaDebug = true` |
Exposing the `tftp` service has to be done differently due to the way TFTP protocol is working.
Either use the host network using the `tftp.hostNetwork` value or configure a load balancer for the `tftp` service.
Note that not all load balancers will work: `serviceLB` implementation is not compatible with TFTP protocol, while MetalLB works.
### Ingress vs Gateway API
The helm chart deploys ingress rules by default.
Switching to [Gateway API](https://gateway-api.sigs.k8s.io/) instead is possible though requires more effort.
The Gateway API implementation used in this helm chart is aligned with the one handled by the traefik shipped with the latest RKE2.
Using the Gateway API routes is still experimental as some of the needed resources, namely `TCPRoute` are not stable yet.
To enable it, set the `gateway.enable` value.
The other values in the `gateway` structure may need to be set depending on the cluster setup.
**Note that on RKE2 1.35 on top of enabling Traefik with Gateway API, the `TLSRoute` and `TCPRoute` CRDs need to be manually added and the Traefik helm chart has to be deployed with the `providers.kubernetesGateway.experimentalChannel`.**
### AppArmor
If the node where the server pod is running has AppArmor, the containerd profile won't let it mount the cgroup2 file system.
This can be addressed in two different ways.
The easiest, but unsafe way is to set `server.superPrivileged=true` value so the server containers run unconfined.
Otherwise set the `server.apparmorProfile` to the name of a profile containing a definition like the following.
If using exactly this content, the name of the profile to use will be `k8s-systemd-uyuni`.
To deploy the AppArmor profile, copy this content to `/etc/apparmor.d/k8s-systemd-uyuni` and run `apparmor_parser -r /etc/apparmor.d/k8s-systemd-uyuni` to load it.
```
#include <tunables/global>
profile k8s-systemd-uyuni flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
#include <abstractions/nameservice>
# Standard container permissions
file,
network,
capability,
ptrace,
unix,
# Deny writes to critical kernel interfaces that systemd doesn't need to change
deny /sys/firmware/** rwklx,
deny /sys/kernel/debug/** rwklx,
# Broadly allow the specific flag combinations used for systemd hardening
# This covers /dev/pts/, /dev/mqueue/, and the previous /etc/ errors.
mount options=(ro, nosuid, noexec, nodev, remount, bind) -> **,
mount options=(ro, nosuid, noexec, remount, bind) -> **,
mount options=(ro, nosuid, nodev, remount, bind) -> **,
mount options=(ro, nosuid, remount, bind) -> **,
mount options=(ro, remount, bind) -> **,
# Allow mount propagation (Required for systemd to function at all)
mount options=(rw, rslave) -> **,
mount options=(rw, slave) -> **,
mount options=(rw, shared) -> **,
# Specific filesystem types for systemd's API mounts
mount fstype=tmpfs options=(rw, nosuid, nodev, noexec) -> /tmp/,
mount fstype=tmpfs options=(rw, nosuid, nodev) -> /tmp/,
mount fstype=tmpfs -> /run/**,
mount fstype=cgroup2 -> /sys/fs/cgroup/,
mount fstype=mqueue -> /dev/mqueue/,
mount fstype=fusectl -> /sys/fs/fuse/connections/,
mount fstype=devpts -> /dev/pts/,
# Generic remounts (for general compatibility)
mount options=(rw, remount) -> **,
mount options=(ro, remount) -> **,
# Required for the uyuni server container specifically
/sys/fs/cgroup/** rw,
/run/** rw,
/var/** rw,
# Allow reading the various config volumes mapped in the chart
/etc/** r,
}
```
### SELinux
If the node where the server pod is running has SELinux and RKE2 is configured to use it, the container won't be able to mount the cgroup2 file system.
This can be addressed in two different ways.
The easiest, but unsafe way is to set `server.superPrivileged=true` value so the server containers run with the `spc_t` label.
Otherwise set the `server.selinuxType` to the name of a custom SELinux type granting only the permissions needed by the server pod.
Defining a dedicated type — rather than extending the generic `container_t` — ensures the extra permissions are not granted to every other container running on the node.
If using exactly the policy below, the name of the type to use will be `uyuni_container_t`.
To deploy the policy, create a `/root/systemdcontainerpolicy.te` file with this content:
```sepolicy
module systemdcontainerpolicy 1.0;
require {
attribute domain;
attribute container_domain;
attribute mcs_constrained_type;
attribute container_net_domain;
attribute svirt_sandbox_domain;
attribute sandbox_net_domain;
attribute syslog_client_type;
attribute can_dump_kernel;
attribute can_receive_kernel_messages;
attribute corenet_unconfined_type;
attribute corenet_unlabeled_type;
attribute kernel_system_state_reader;
attribute pcmcia_typeattr_1;
attribute process_user_target;
role system_r;
type cgroup_t;
type tmpfs_t;
type proc_t;
class dir { search write add_name create remove_name rmdir setattr getattr mounton };
class file { create open write append read unlink setattr getattr watch };
class filesystem { mount getattr relabelfrom relabelto remount unmount };
class netlink_audit_socket { nlmsg_relay };
}
# Declare the uyuni_container_t type and associate it with standard container attributes.
type uyuni_container_t, domain, container_domain, container_net_domain, mcs_constrained_type, svirt_sandbox_domain, sandbox_net_domain, syslog_client_type, can_dump_kernel, can_receive_kernel_messages, corenet_unconfined_type, corenet_unlabeled_type, kernel_system_state_reader, pcmcia_typeattr_1, process_user_target;
# Associate with the system_r role
role system_r types uyuni_container_t;
#============= uyuni_container_t ==============
allow uyuni_container_t cgroup_t:dir { add_name create remove_name rmdir setattr write search getattr };
allow uyuni_container_t cgroup_t:file { create open write append read setattr getattr unlink watch };
allow uyuni_container_t cgroup_t:filesystem { mount getattr relabelfrom relabelto };
# Allow systemd's credential helper (sd-mkdcreds) to use /dev/shm as a mount point for service credentials.
allow uyuni_container_t tmpfs_t:dir mounton;
# Standard lookups and attributes for the mount point
allow uyuni_container_t tmpfs_t:dir { getattr search };
# Allow systemd to mount/remount the proc filesystem for namespacing
allow uyuni_container_t proc_t:filesystem { mount remount unmount };
# Required to use directories as mount points
allow uyuni_container_t proc_t:dir mounton;
# Allow su and PAM inside the container to log audits to the kernel
allow uyuni_container_t self:netlink_audit_socket { nlmsg_relay };
```
Then compile and load it:
```sh
checkmodule -M -m -o /root/systemdcontainerpolicy.mod /root/systemdcontainerpolicy.te
semodule_package -o /root/systemdcontainerpolicy.pp -m /root/systemdcontainerpolicy.mod
semodule -i /root/systemdcontainerpolicy.pp
```
## Usage
Once installed, the web interface can be accessed directly on the configured FQDN.
## More Info
Check the product documentation: https://www.uyuni-project.org/uyuni-docs

View file

@ -0,0 +1,6 @@
Thank you for installing the {{ .Chart.Description }}!
Connect to the web UI using the credentials from the admin-credentials secret:
https://{{ .Values.global.fqdn }}
Documentation can be found at {{ .Chart.Home }}

View file

@ -0,0 +1,107 @@
{{/* uyuni.image computes the image URL out of the global registry and tag as well as overridden values. */}}
{{/* "name", the image name */}}
{{/* "global", the root object */}}
{{/* "local", the configuration object containing the image and tag to override with */}}
{{- define "uyuni.image" -}}
{{- $tag := .global.Values.tag -}}
{{- if .local.tag -}}
{{- $tag = .local.tag -}}
{{- end -}}
{{- $uri := (printf "%s/%s:%s" (required "The repository value is required!" .global.Values.repository) .name $tag) -}}
{{- if .local.image -}}
{{- $uri = (printf "%s:%s" .local.image $tag) -}}
{{- end -}}
{{- $uri -}}
{{- end -}}
{{/* uyuni.pvc writes the manifest for a PVC. */}}
{{/* "root", the top context, */}}
{{/* "name", the volume name, */}}
{{/* "volume", the volume config data dictionary of the volume, */}}
{{/* "defaultSize", the default size of the volume in case the user messes it up in the values, */}}
{{/* "accessMode", the access mode to use for the volume */}}
{{- define "uyuni.pvc" -}}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .name }}
namespace: {{ .root.Release.Namespace | quote }}
labels:
app.kubernetes.io/part-of: uyuni
{{- if .volume.extraLabels }}
{{ toYaml .volume.extraLabels | nindent 4 }}
{{- end }}
{{- if .volume.annotations }}
annotations:
{{ toYaml .volume.annotations | nindent 4 }}
{{- end }}
spec:
{{- $storageClass := .root.Values.volumes.storageClass }}
{{- if .volume.storageClass }}
{{ $storageClass = .volume.storageClass }}
{{- end }}
{{- if $storageClass }}
{{- if eq "-" $storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $storageClass | quote }}
{{- end }}
{{- end }}
accessModes:
- {{ .accessMode }}
resources:
requests:
storage: {{ .volume.size | default .defaultSize | quote }}
{{- if .volume.volumeName }}
volumeName: {{ .volume.volumeName | quote }}
{{- end }}
{{- if .volume.selector }}
selector:
{{ toYaml .volume.selector | nindent 4 }}
{{- end }}
---
{{- end -}}
{{- define "uyuni.pgPVCName" -}}
var-pgsql18
{{- end -}}
{{/* uyuni.nodePlacement writes the node placement properties for a pod */}}
{{/* "global": the global placement configuration data */}}
{{/* "local": the overwriting configurantion data */}}
{{- define "uyuni.nodePlacement" -}}
{{- $globalNode := .global | default (dict) -}}
{{- $localNode := .local | default (dict) -}}
{{- /* Handle nodeSelector */ -}}
{{- $nodeSelector := $globalNode.nodeSelector -}}
{{- if $localNode.nodeSelector }}{{ $nodeSelector = $localNode.nodeSelector }}{{ end -}}
{{- if $nodeSelector }}
nodeSelector:
{{- toYaml $nodeSelector | nindent 2 }}
{{- end }}
{{- /* Handle affinity */ -}}
{{- $affinity := $globalNode.affinity -}}
{{- if $localNode.affinity }}{{ $affinity = $localNode.affinity }}{{ end -}}
{{- if $affinity }}
affinity:
{{- toYaml $affinity | nindent 2 }}
{{- end }}
{{- /* Handle tolerations */ -}}
{{- $tolerations := $globalNode.tolerations -}}
{{- if $localNode.tolerations }}{{ $tolerations = $localNode.tolerations }}{{ end -}}
{{- if $tolerations }}
tolerations:
{{- toYaml $tolerations | nindent 2 }}
{{- end }}
{{- /* Handle nodeName */ -}}
{{- $nodeName := $globalNode.nodeName -}}
{{- if $localNode.nodeName }}{{ $nodeName = $localNode.nodeName }}{{ end -}}
{{- if $nodeName }}
nodeName: {{ $nodeName | quote }}
{{- end }}
{{- end -}}

View file

@ -0,0 +1,97 @@
{{- if gt (default .Values.coco.replicas 0 | int) 0 }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: coco-attestation
app.kubernetes.io/part-of: uyuni
name: coco-attestation
namespace: "{{ .Release.Namespace }}"
spec:
replicas: {{ default .Values.coco.replicas 0 | int }}
selector:
matchLabels:
app.kubernetes.io/component: coco-attestation
app.kubernetes.io/part-of: uyuni
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/component: coco-attestation
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.coco) | nindent 6 }}
containers:
- env:
- name: database_user
valueFrom:
secretKeyRef:
key: username
name: db-credentials
optional: false
- name: database_password
valueFrom:
secretKeyRef:
key: password
name: db-credentials
optional: false
- name: database_host
valueFrom:
configMapKeyRef:
key: db_host
name: uyuni-config
optional: false
- name: database_port
valueFrom:
configMapKeyRef:
key: db_port
name: uyuni-config
optional: false
- name: database_name
valueFrom:
configMapKeyRef:
key: db_name
name: uyuni-config
optional: false
image: {{ include "uyuni.image" (dict "name" "server-attestation" "global" . "local" .Values.coco) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: coco
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
initContainers:
- command:
- sh
- -c
- |2
until pg_isready -U $MANAGER_USER -h $MANAGER_DB_HOST -p $MANAGER_DB_PORT -d $MANAGER_DB_NAME; do
sleep 60
done
env:
- name: MANAGER_DB_HOST
valueFrom:
configMapKeyRef:
key: db_host
name: uyuni-config
optional: false
- name: MANAGER_DB_PORT
valueFrom:
configMapKeyRef:
key: db_port
name: uyuni-config
optional: false
- name: MANAGER_DB_NAME
value: susemanager
- name: MANAGER_USER
valueFrom:
configMapKeyRef:
key: db_name
name: uyuni-config
optional: false
image: {{ include "uyuni.image" (dict "name" "server" "global" . "local" .Values.server) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: db-waiter
{{- end }}

View file

@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/part-of: uyuni
name: uyuni-config
namespace: "{{ .Release.Namespace }}"
data:
fqdn: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
email: {{ required "server.email is needed!" .Values.server.email }}
{{- if .Values.db.enable }}
db_host: db
db_port: "5432"
db_name: "susemanager"
reportdb_host: reportdb
reportdb_port: "5432"
reportdb_name: reportdb
{{- else }}
db_host: {{ .Values.db.internal.host | default "db" }}
db_port: "{{ .Values.db.internal.port | default 5432 }}"
db_name: {{ .Values.db.internal.name | default "susemanager " }}
reportdb_host: {{ .Values.db.report.host | default "reportdb" }}
reportdb_port: "{{ .Values.db.report.port | default 5432 }}"
reportdb_name: {{ .Values.db.report.name | default "reportdb" }}
{{- end }}

View file

@ -0,0 +1,90 @@
{{- if .Values.db.enable }}
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
name: db
namespace: "{{ .Release.Namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.db) | nindent 6 }}
containers:
- env:
- name: TZ
value: {{ .Values.timezone | default "Etc/UTC" }}
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
key: username
name: db-admin-credentials
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: db-admin-credentials
- name: MANAGER_USER
valueFrom:
secretKeyRef:
key: username
name: db-credentials
- name: MANAGER_PASS
valueFrom:
secretKeyRef:
key: password
name: db-credentials
- name: REPORT_DB_USER
valueFrom:
secretKeyRef:
key: username
name: reportdb-credentials
- name: REPORT_DB_PASS
valueFrom:
secretKeyRef:
key: password
name: reportdb-credentials
image: {{ include "uyuni.image" (dict "name" "server-postgresql" "global" . "local" .Values.db) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: db
volumeMounts:
- mountPath: /var/lib/pgsql/data
subPath: data
name: var-pgsql
- mountPath: /etc/pki
name: tls-secret
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
securityContext:
fsGroup: 999
volumes:
- name: var-pgsql
persistentVolumeClaim:
claimName: {{ include "uyuni.pgPVCName" . }}
- name: tls-secret
secret:
items:
- key: tls.crt
path: tls/certs/spacewalk.crt
- key: tls.key
mode: 256
path: tls/private/pg-spacewalk.key
- key: ca.crt
path: trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT
secretName: db-cert
{{- end }}

View file

@ -0,0 +1,86 @@
{{- if and .Values.gateway.enable (eq .Values.gateway.name "") }}
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: uyuni-gateway
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
gatewayClassName: "{{ .Values.gateway.class }}"
listeners:
# HTTP/HTTPS Listeners
- name: {{ default .Values.gateway.listeners.http.name "web" }}
protocol: HTTP
port: {{ default .Values.gateway.listeners.http.port 8000 }}
allowedRoutes:
namespaces:
from: Same
- name: {{ default .Values.gateway.listeners.http.name "websecure" }}
protocol: HTTPS
port: {{ default .Values.gateway.listeners.https.port 8443 }}
tls:
mode: Terminate
certificateRefs:
- name: uyuni-cert
allowedRoutes:
namespaces:
from: Same
# TCP Listeners
{{- if ne (default .Values.services.type .Values.services.salt.type) "NodePort" }}
- name: salt-publish
protocol: TCP
port: 4505
allowedRoutes:
namespaces:
from: Same
- name: salt-request
protocol: TCP
port: 4506
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- if and .Values.db.enable (ne (default .Values.services.type .Values.services.reportdb.type) "NodePort") }}
- name: reportdb-pgsql
protocol: TCP
port: 5432
allowedRoutes:
namespaces:
from: Same
{{- end }}
# Debug TCP Listeners
{{- if .Values.exposeJavaDebug }}
{{- if ne (default .Values.services.type .Values.services.taskomatic.type) "NodePort" }}
- name: tasko-debug
protocol: TCP
port: 8001
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- if ne (default .Values.services.type .Values.services.search.type) "NodePort" }}
- name: search-debug
protocol: TCP
port: 8002
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- if ne (default .Values.services.type .Values.services.tomcat.type) "NodePort" }}
- name: tomcat-debug
protocol: TCP
port: 8003
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,51 @@
{{- if default .Values.hubAPI.enable false }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: hub-xmlrpc
app.kubernetes.io/part-of: uyuni
name: hub-xmlrpc
namespace: "{{ .Release.Namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: hub-xmlrpc
app.kubernetes.io/part-of: uyuni
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/component: hub-xmlrpc
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.hubAPI) | nindent 6 }}
containers:
- env:
- name: HUB_API_URL
value: http://web/rpc/api
- name: HUB_CONNECT_USING_SSL
value: "true"
image: {{ include "uyuni.image" (dict "name" "server-hub-xmlrpc-api" "global" . "local" .Values.hubAPI) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: hub-xmlrpc
ports:
- containerPort: 2830
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
initContainers:
- command:
- sh
- -c
- |2
until curl -L http://web/rhn/manager/api/api/getVersion; do
sleep 60
done
image: {{ include "uyuni.image" (dict "name" "server-hub-xmlrpc-api" "global" . "local" .Values.hubAPI) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: server-waiter
{{- end }}

View file

@ -0,0 +1,431 @@
{{- if not .Values.gateway.enable }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: uyuni-ingress-ssl
namespace: "{{ .Release.Namespace }}"
annotations:
{{- if eq ((.Values.ingress).type) "traefik" }}
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.tls.domains.n.main: "{{ required "global.fqdn is needed!" .Values.global.fqdn }}"
traefik.ingress.kubernetes.io/router.entrypoints: "websecure"
traefik.ingress.kubernetes.io/router.priority: "1"
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-strip-prefixes@kubernetescrd"
{{- end }}
{{- if (((.Values.ingress).annotations).ssl) }}
{{ toYaml .Values.ingress.annotations.ssl | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: server
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
tls:
- hosts:
- {{ required "global.fqdn is needed!" .Values.global.fqdn }}
secretName: uyuni-cert
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- path: /
backend:
service:
name: web
port:
number: 80
pathType: Prefix
{{- if ne .Values.enableMonitoring false }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: exporters-ingress-ssl
namespace: "{{ .Release.Namespace }}"
annotations:
{{- if eq ((.Values.ingress).type) "traefik" }}
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.tls.domains.n.main: "{{ required "global.fqdn is needed!" .Values.global.fqdn }}"
traefik.ingress.kubernetes.io/router.entrypoints: "websecure"
traefik.ingress.kubernetes.io/router.priority: "100"
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-strip-prefixes@kubernetescrd"
{{- end }}
{{- if (((.Values.ingress).annotations).exporters) }}
{{ toYaml .Values.ingress.annotations.exporters | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: server
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
tls:
- hosts:
- {{ required "global.fqdn is needed!" .Values.global.fqdn }}
secretName: uyuni-cert
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- path: /postgresql-exporter
backend:
service:
name: tomcat-internal
port:
number: 9187
pathType: Prefix
- path: /node-exporter
backend:
service:
name: tomcat-internal
port:
number: 9100
pathType: Prefix
- path: /tasko-exporter
backend:
service:
name: taskomatic-internal
port:
number: 9800
pathType: Prefix
- path: /tasko-jmx
backend:
service:
name: taskomatic-internal
port:
number: 5557
pathType: Prefix
- path: /tomcat-jmx
backend:
service:
name: tomcat-internal
port:
number: 5556
pathType: Prefix
{{- end }}
{{- if .Values.saline.enable }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: saline-ingress-ssl
namespace: "{{ .Release.Namespace }}"
annotations:
{{- if eq ((.Values.ingress).type) "traefik" }}
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.tls.domains.n.main: "{{ required "global.fqdn is needed!" .Values.global.fqdn }}"
traefik.ingress.kubernetes.io/router.entrypoints: "websecure"
traefik.ingress.kubernetes.io/router.priority: "100"
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-strip-prefixes@kubernetescrd"
{{- end }}
{{- if (((.Values.ingress).annotations).saline) }}
{{ toYaml .Values.ingress.annotations.saline | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: saline
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
tls:
- hosts:
- {{ required "global.fqdn is needed!" .Values.global.fqdn }}
secretName: uyuni-cert
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- backend:
service:
name: saline
port:
number: 8216
path: /saline
pathType: Prefix
{{- end }}
{{- if default .Values.hubAPI.enable false }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: hubapi-ingress-ssl
namespace: "{{ .Release.Namespace }}"
annotations:
{{- if eq ((.Values.ingress).type) "traefik" }}
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.tls.domains.n.main: "{{ required "global.fqdn is needed!" .Values.global.fqdn }}"
traefik.ingress.kubernetes.io/router.entrypoints: "websecure"
traefik.ingress.kubernetes.io/router.priority: "100"
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-strip-prefixes@kubernetescrd"
{{- end }}
{{- if (((.Values.ingress).annotations).hub) }}
{{ toYaml .Values.ingress.annotations.hub | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: hub-xmlrpc
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
tls:
- hosts:
- {{ required "global.fqdn is needed!" .Values.global.fqdn }}
secretName: uyuni-cert
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- path: /hub/rpc/api
backend:
service:
name: hub-xmlrpc
port:
number: 2830
pathType: Prefix
{{- end }}
{{- if eq ((.Values.ingress).type) "traefik" }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: uyuni-ingress-ssl-redirect
namespace: "{{ .Release.Namespace }}"
annotations:
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-https-redirect@kubernetescrd"
traefik.ingress.kubernetes.io/router.entrypoints: "web"
traefik.ingress.kubernetes.io/router.priority: "1"
{{- if (((.Values.ingress).annotations).sslRedirect) }}
{{ toYaml .Values.ingress.annotations.sslRedirect | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: server
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- backend:
service:
name: web
port:
number: 80
path: /
pathType: Prefix
{{- if default .Values.hubAPI.enable false }}
- backend:
service:
name: hub-xmlrpc
port:
number: 2830
path: /hub/rpc/api
pathType: Prefix
{{- end }}
{{- end }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: uyuni-ingress-nossl
namespace: "{{ .Release.Namespace }}"
annotations:
{{- if eq ((.Values.ingress).type) "traefik" }}
traefik.ingress.kubernetes.io/router.tls: "false"
traefik.ingress.kubernetes.io/router.entrypoints: "web"
traefik.ingress.kubernetes.io/router.priority: "100"
traefik.ingress.kubernetes.io/router.middlewares: "{{ .Release.Namespace }}-uyuni-strip-prefixes@kubernetescrd"
{{- end }}
{{- if (((.Values.ingress).annotations).nossl) }}
{{ toYaml .Values.ingress.annotations.nossl | indent 4 }}
{{- end }}
labels:
app.kubernetes.io/part-of: uyuni
app.kubernetes.io/component: server
spec:
{{- if ((.Values.ingress).class) }}
ingressClassName: {{ .Values.ingress.class }}
{{- end }}
rules:
- host: {{ required "global.fqdn is needed!" .Values.global.fqdn }}
http:
paths:
- backend:
service:
name: web
port:
number: 80
path: /pub
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/kickstart/DownloadFile
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/common/DownloadFile
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/rpc/api
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rpc/api
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/errors
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/ty/TinyUrl
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/websocket
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /rhn/metrics
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /cobbler_api
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /cblr
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /httpboot
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /images
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /cobbler
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /os-images
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /tftp
pathType: Prefix
- backend:
service:
name: web
port:
number: 80
path: /docs
pathType: Prefix
{{- if ne .Values.enableMonitoring false }}
- path: /postgresql-exporter
backend:
service:
name: tomcat-internal
port:
number: 9187
pathType: Prefix
- path: /node-exporter
backend:
service:
name: tomcat-internal
port:
number: 9100
pathType: Prefix
- path: /tasko-exporter
backend:
service:
name: taskomatic-internal
port:
number: 9800
pathType: Prefix
- path: /tasko-jmx
backend:
service:
name: taskomatic-internal
port:
number: 5557
pathType: Prefix
- path: /tomcat-jmx
backend:
service:
name: tomcat-internal
port:
number: 5556
pathType: Prefix
{{- end }}
{{- if .Values.saline.enable }}
- backend:
service:
name: saline
port:
number: 8216
path: /saline
pathType: Prefix
{{- end }}
{{- end }}

View file

@ -0,0 +1,27 @@
{{ include "uyuni.pvc" (dict "root" . "name" "ca-certs" "volume" (index .Values.volumes "ca-certs") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-apache2" "volume" (index .Values.volumes "etc-apache2") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-cobbler" "volume" (index .Values.volumes "etc-cobbler") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-postfix" "volume" (index .Values.volumes "etc-postfix") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-rhn" "volume" (index .Values.volumes "etc-rhn") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-salt" "volume" (index .Values.volumes "etc-salt") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-sssd" "volume" (index .Values.volumes "etc-sssd") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-sysconfig" "volume" (index .Values.volumes "etc-sysconfig") "defaultSize" "20Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-systemd-multi" "volume" (index .Values.volumes "etc-systemd-multi") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-systemd-sockets" "volume" (index .Values.volumes "etc-systemd-sockets") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "etc-tomcat" "volume" (index .Values.volumes "etc-tomcat") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "run-salt-master" "volume" (index .Values.volumes "run-salt-master") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-formulametadata" "volume" (index .Values.volumes "srv-formulametadata") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-pillar" "volume" (index .Values.volumes "srv-pillar") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-salt" "volume" (index .Values.volumes "srv-salt") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-spacewalk" "volume" (index .Values.volumes "srv-spacewalk") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-susemanager" "volume" (index .Values.volumes "srv-susemanager") "defaultSize" "1Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-tftpboot" "volume" (index .Values.volumes "srv-tftpboot") "defaultSize" "300Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "srv-www" "volume" (index .Values.volumes "srv-www") "defaultSize" "100Gi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-cache" "volume" (index .Values.volumes "var-cache") "defaultSize" "10Gi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-cobbler" "volume" (index .Values.volumes "var-cobbler") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-log" "volume" (index .Values.volumes "var-log") "defaultSize" "2Gi" "accessMode" "ReadWriteOnce") }}
{{- $pgPVCName := include "uyuni.pgPVCName" . }}
{{ include "uyuni.pvc" (dict "root" . "name" $pgPVCName "volume" (index .Values.volumes "var-pgsql") "defaultSize" "50Gi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-salt" "volume" (index .Values.volumes "var-salt") "defaultSize" "10Mi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-search" "volume" (index .Values.volumes "var-search") "defaultSize" "10Gi" "accessMode" "ReadWriteOnce") }}
{{ include "uyuni.pvc" (dict "root" . "name" "var-spacewalk" "volume" (index .Values.volumes "var-spacewalk") "defaultSize" "100Gi" "accessMode" "ReadWriteOnce") }}

View file

@ -0,0 +1,226 @@
{{- if .Values.gateway.enable }}
{{- $fqdn := required "global.fqdn is needed!" .Values.global.fqdn -}}
{{- $gatewayName := .Values.gateway.name | default "uyuni-gateway" -}}
# SSL Redirection (Port 80 to 443)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: uyuni-ssl-redirect
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: {{ .Values.gateway.listeners.http.name }}
hostnames:
- {{ $fqdn | quote }}
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
---
# HTTPS Routes
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: uyuni-https-routes
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: {{ .Values.gateway.listeners.https.name }}
hostnames:
- {{ $fqdn | quote }}
rules:
{{- if ne .Values.enableMonitoring false }}
# postgresql exporter
- matches:
- path: { type: PathPrefix, value: /postgresql-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 9187
# Node exporter
- matches:
- path: { type: PathPrefix, value: /node-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 9100
# Tomcat Monitoring JMX
- matches:
- path: { type: PathPrefix, value: /tomcat-jmx }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 5556
# Taskomatic Monitoring Exporter
- matches:
- path: { type: PathPrefix, value: /tasko-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: taskomatic-internal
port: 9800
# Taskomatic Monitoring JMX
- matches:
- path: { type: PathPrefix, value: /tasko-jmx }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: taskomatic-internal
port: 5557
{{- end }}
{{- if .Values.saline.enable }}
- matches:
- path: { type: PathPrefix, value: /saline }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: saline
port: 8216
{{- end }}
{{- if default .Values.hubAPI.enable false }}
- matches:
- path: { type: PathPrefix, value: /hub/rpc/api }
backendRefs:
- name: hub-xmlrpc
port: 2830
{{- end }}
- matches:
- path: { type: PathPrefix, value: / }
backendRefs:
- name: web
port: 80
---
# Non-SSL Paths
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: uyuni-nossl-routes
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: {{ .Values.gateway.listeners.http.name }}
hostnames:
- {{ $fqdn | quote }}
rules:
# Standard Non-SSL Paths
- matches:
- path: { type: PathPrefix, value: /pub }
- path: { type: PathPrefix, value: /rhn/kickstart/DownloadFile }
- path: { type: PathPrefix, value: /rhn/common/DownloadFile }
- path: { type: PathPrefix, value: /rhn/rpc/api }
- path: { type: PathPrefix, value: /rpc/api }
- path: { type: PathPrefix, value: /rhn/errors }
- path: { type: PathPrefix, value: /rhn/ty/TinyUrl }
- path: { type: PathPrefix, value: /rhn/websocket }
- path: { type: PathPrefix, value: /rhn/metrics }
- path: { type: PathPrefix, value: /cobbler_api }
- path: { type: PathPrefix, value: /cobbler }
- path: { type: PathPrefix, value: /cblr }
- path: { type: PathPrefix, value: /httpboot }
- path: { type: PathPrefix, value: /images }
- path: { type: PathPrefix, value: /os-images }
- path: { type: PathPrefix, value: /tftp }
- path: { type: PathPrefix, value: /docs }
backendRefs:
- name: web
port: 80
{{- if ne .Values.enableMonitoring false }}
# postgresql exporter
- matches:
- path: { type: PathPrefix, value: /postgresql-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 9187
# Node exporter
- matches:
- path: { type: PathPrefix, value: /node-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 9100
# Tomcat Monitoring JMX
- matches:
- path: { type: PathPrefix, value: /tomcat-jmx }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: tomcat-internal
port: 5556
# Taskomatic Monitoring Exporter
- matches:
- path: { type: PathPrefix, value: /tasko-exporter }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: taskomatic-internal
port: 9800
# Taskomatic Monitoring JMX
- matches:
- path: { type: PathPrefix, value: /tasko-jmx }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: taskomatic-internal
port: 5557
{{- end }}
{{- if .Values.saline.enable }}
- matches:
- path: { type: PathPrefix, value: /saline }
filters:
- type: URLRewrite
urlRewrite:
path: { type: ReplacePrefixMatch, replacePrefixMatch: / }
backendRefs:
- name: saline
port: 8216
{{- end }}
{{- end }}

View file

@ -0,0 +1,67 @@
{{- if default .Values.saline.enable false }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: saline
app.kubernetes.io/part-of: uyuni
name: saline
namespace: "{{ .Release.Namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: saline
app.kubernetes.io/part-of: uyuni
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/component: saline
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.saline) | nindent 6 }}
containers:
- env:
- name: NOSSL
value: "YES"
- name: TZ
value: {{ .Values.timezone | default "Etc/UTC" }}
image: {{ include "uyuni.image" (dict "name" "server-saline" "global" . "local" .Values.saline) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: saline
ports:
- containerPort: 8216
volumeMounts:
- mountPath: /run/salt/master
name: run-salt-master
- mountPath: /etc/salt
name: etc-salt
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
initContainers:
- command:
- sh
- -c
- |2
until curl -L http://web/rhn/manager/api/api/getVersion; do
sleep 60
done
image: {{ include "uyuni.image" (dict "name" "server-saline" "global" . "local" .Values.saline) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: server-waiter
securityContext:
seLinuxOptions:
level: "s0"
volumes:
- name: run-salt-master
persistentVolumeClaim:
claimName: run-salt-master
- name: etc-salt
persistentVolumeClaim:
claimName: etc-salt
{{- end }}

View file

@ -0,0 +1,552 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: uyuni
namespace: "{{ .Release.Namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.server) | nindent 6 }}
containers:
- env:
- name: container
value: oci
- name: TZ
value: {{ .Values.timezone | default "Etc/UTC" }}
{{- if and .Values.server.mirror (or .Values.server.mirror.claimName .Values.server.mirror.hostPath) }}
- name: MIRROR_PATH
value: /mirror
{{- end }}
- name: ADMIN_USER
valueFrom:
secretKeyRef:
key: username
name: admin-credentials
optional: false
- name: ADMIN_PASS
valueFrom:
secretKeyRef:
key: password
name: admin-credentials
optional: false
- name: MANAGER_USER
valueFrom:
secretKeyRef:
key: username
name: db-credentials
optional: false
- name: MANAGER_PASS
valueFrom:
secretKeyRef:
key: password
name: db-credentials
optional: false
- name: REPORT_DB_USER
valueFrom:
secretKeyRef:
key: username
name: reportdb-credentials
optional: false
- name: REPORT_DB_PASS
valueFrom:
secretKeyRef:
key: password
name: reportdb-credentials
optional: false
- name: MANAGER_DB_NAME
value: susemanager
- name: MANAGER_DB_HOST
value: db
- name: MANAGER_DB_CA_CERT
value: /etc/pki/trust/anchors/DB-RHN-ORG-TRUSTED-SSL-CERT
- name: MANAGER_DB_PORT
value: "5432"
- name: EXTERNALDB_PROVIDER
- name: ISS_PARENT
- name: REPORT_DB_NAME
value: reportdb
- name: REPORT_DB_HOST
value: reportdb
- name: REPORT_DB_CA_CERT
value: /etc/pki/trust/anchors/DB-RHN-ORG-TRUSTED-SSL-CERT
- name: REPORT_DB_PORT
value: "5432"
- name: MANAGER_ADMIN_EMAIL
valueFrom:
configMapKeyRef:
key: email
name: uyuni-config
optional: false
- name: MANAGER_MAIL_FROM
valueFrom:
configMapKeyRef:
key: email
name: uyuni-config
optional: false
- name: UYUNI_HOSTNAME
valueFrom:
configMapKeyRef:
key: fqdn
name: uyuni-config
optional: false
{{- if .Values.exposeJavaDebug }}
- name: DEBUG_JAVA
value: "true"
{{- end }}
{{- if .Values.server.sccSecret }}
- name: SCC_USER
valueFrom:
secretKeyRef:
key: username
name: {{ .Values.server.sccSecret }}
optional: false
- name: SCC_PASS
valueFrom:
secretKeyRef:
key: password
name: {{ .Values.server.sccSecret }}
optional: false
{{- end }}
{{- if .Values.server.systemdLogLevel }}
- name: SYSTEMD_LOG_TARGET
value: console
- name: SYSTEMD_LOG_LEVEL
value: {{ .Values.server.systemdLogLevel }}
tty: true
{{- end }}
image: {{ include "uyuni.image" (dict "name" "server" "global" . "local" .Values.server) }}
imagePullPolicy: {{ .Values.pullPolicy }}
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- spacewalk-service stop
name: uyuni
securityContext:
capabilities:
add:
- SYS_ADMIN
seLinuxOptions:
level: "s0"
{{- if .Values.server.superPrivileged }}
type: "spc_t"
{{- else if .Values.server.selinuxType }}
type: {{ .Values.server.selinuxType | quote }}
{{- end }}
{{- if .Values.server.superPrivileged }}
appArmorProfile:
type: Unconfined
{{- else if .Values.server.apparmorProfile }}
appArmorProfile:
type: Localhost
localhostProfile: {{ .Values.server.apparmorProfile }}
{{- end }}
ports:
- containerPort: 80
- containerPort: 4505
- containerPort: 4506
- containerPort: 25151
{{- if .Values.exposeJavaDebug | default false }}
- containerPort: 8001
- containerPort: 8002
- containerPort: 8003
{{- end }}
- containerPort: 9100
{{- if ne .Values.enableMonitoring false }}
- containerPort: 5556
- containerPort: 5557
- containerPort: 9187
- containerPort: 9800
{{- end }}
startupProbe:
exec:
command:
- /usr/bin/startup-check.sh
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3600 # Max 10h
livenessProbe:
exec:
command:
- /usr/bin/liveness-check.sh
timeoutSeconds: 5
failureThreshold: 5
periodSeconds: 60
readinessProbe:
httpGet:
path: /rhn/manager/api/api/getVersion
port: 80
scheme: HTTP
periodSeconds: 10
successThreshold: 1
initialDelaySeconds: 120
volumeMounts:
- mountPath: /var/lib/cobbler
name: var-cobbler
- mountPath: /var/lib/rhn/search
name: var-search
- mountPath: /var/lib/salt
name: var-salt
- mountPath: /var/cache
name: var-cache
- mountPath: /var/spacewalk
name: var-spacewalk
- mountPath: /var/log
name: var-log
- mountPath: /srv/salt
name: srv-salt
- mountPath: /srv/www/
name: srv-www
- mountPath: /srv/tftpboot
name: srv-tftpboot
- mountPath: /srv/formula_metadata
name: srv-formulametadata
- mountPath: /srv/pillar
name: srv-pillar
- mountPath: /srv/susemanager
name: srv-susemanager
- mountPath: /srv/spacewalk
name: srv-spacewalk
- mountPath: /etc/pki/trust/anchors/
name: ca-certs
- mountPath: /run/salt/master
name: run-salt-master
- mountPath: /etc/apache2
name: etc-apache2
- mountPath: /etc/systemd/system/multi-user.target.wants
name: etc-systemd-multi
- mountPath: /etc/systemd/system/sockets.target.wants
name: etc-systemd-sockets
- mountPath: /etc/salt
name: etc-salt
- mountPath: /etc/tomcat
name: etc-tomcat
- mountPath: /etc/cobbler
name: etc-cobbler
- mountPath: /etc/sysconfig
name: etc-sysconfig
- mountPath: /etc/postfix
name: etc-postfix
- mountPath: /etc/sssd
name: etc-sssd
- mountPath: /etc/rhn
name: etc-rhn
- mountPath: /etc/pki/trust/anchors/LOCAL-RHN-ORG-TRUSTED-SSL-CERT
name: ca-cert
readOnly: true
subPath: ca.crt
- mountPath: /usr/share/susemanager/salt/certs/RHN-ORG-TRUSTED-SSL-CERT
name: ca-cert
readOnly: true
subPath: ca.crt
- mountPath: /srv/www/htdocs/pub/RHN-ORG-TRUSTED-SSL-CERT
name: ca-cert
readOnly: true
subPath: ca.crt
- mountPath: /etc/pki/trust/anchors/DB-RHN-ORG-TRUSTED-SSL-CERT
name: db-ca-cert
readOnly: true
subPath: ca.crt
- mountPath: /etc/pki/
name: tls
- mountPath: /run
name: run
- mountPath: /sys/fs/cgroup
name: sys-fs-cgroup
{{- if and .Values.server.mirror (or .Values.server.mirror.claimName .Values.server.mirror.hostPath) }}
- name: mirror
mountPath: /mirror
{{- end }}
{{- if .Values.server.extraVolumeMounts }}
{{ toYaml .Values.server.extraVolumeMounts | nindent 8 }}
{{- end }}
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
initContainers:
- command:
- sh
- -x
- -c
- |2
# Fill the empty volumes
for vol in /var/lib/cobbler \
/var/lib/rhn/search \
/var/lib/salt \
/var/cache \
/var/log \
/srv/salt \
/srv/www \
/srv/tftpboot \
/srv/formula_metadata \
/srv/pillar \
/srv/susemanager \
/srv/spacewalk \
/etc/apache2 \
/etc/rhn \
/etc/systemd/system/multi-user.target.wants \
/etc/systemd/system/sockets.target.wants \
/etc/salt \
/etc/tomcat \
/etc/cobbler \
/etc/sysconfig \
/etc/postfix \
/etc/sssd
do
chown --reference=$vol /mnt$vol;
chmod --reference=$vol /mnt$vol;
if [ -z "$(ls -A /mnt$vol)" ]; then
cp -a $vol/. /mnt$vol;
fi
done
image: {{ include "uyuni.image" (dict "name" "server" "global" . "local" .Values.server) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: init-volumes
securityContext:
seLinuxOptions:
level: "s0"
volumeMounts:
- mountPath: /mnt/var/lib/cobbler
name: var-cobbler
- mountPath: /mnt/var/lib/rhn/search
name: var-search
- mountPath: /mnt/var/lib/salt
name: var-salt
- mountPath: /mnt/var/cache
name: var-cache
- mountPath: /mnt/var/spacewalk
name: var-spacewalk
- mountPath: /mnt/var/log
name: var-log
- mountPath: /mnt/srv/salt
name: srv-salt
- mountPath: /mnt/srv/www/
name: srv-www
- mountPath: /mnt/srv/tftpboot
name: srv-tftpboot
- mountPath: /mnt/srv/formula_metadata
name: srv-formulametadata
- mountPath: /mnt/srv/pillar
name: srv-pillar
- mountPath: /mnt/srv/susemanager
name: srv-susemanager
- mountPath: /mnt/srv/spacewalk
name: srv-spacewalk
- mountPath: /mnt/etc/pki/trust/anchors/
name: ca-certs
- mountPath: /mnt/run/salt/master
name: run-salt-master
- mountPath: /mnt/etc/apache2
name: etc-apache2
- mountPath: /mnt/etc/systemd/system/multi-user.target.wants
name: etc-systemd-multi
- mountPath: /mnt/etc/systemd/system/sockets.target.wants
name: etc-systemd-sockets
- mountPath: /mnt/etc/salt
name: etc-salt
- mountPath: /mnt/etc/tomcat
name: etc-tomcat
- mountPath: /mnt/etc/cobbler
name: etc-cobbler
- mountPath: /mnt/etc/sysconfig
name: etc-sysconfig
- mountPath: /mnt/etc/postfix
name: etc-postfix
- mountPath: /mnt/etc/sssd
name: etc-sssd
- mountPath: /mnt/etc/rhn
name: etc-rhn
- command:
- sh
- -c
- |2
until pg_isready -U $MANAGER_USER -h $MANAGER_DB_HOST -p $MANAGER_DB_PORT -d $MANAGER_DB_NAME; do
sleep 60
done
until pg_isready -U $REPORT_DB_USER -h $REPORT_DB_HOST -p $REPORT_DB_PORT -d $REPORT_DB_NAME; do
sleep 60
done
env:
- name: MANAGER_DB_HOST
valueFrom:
configMapKeyRef:
key: "db_host"
name: uyuni-config
optional: false
- name: MANAGER_DB_PORT
valueFrom:
configMapKeyRef:
key: "db_port"
name: uyuni-config
optional: false
- name: MANAGER_DB_NAME
valueFrom:
configMapKeyRef:
key: "db_name"
name: uyuni-config
optional: false
- name: MANAGER_USER
valueFrom:
secretKeyRef:
key: username
name: db-credentials
optional: false
- name: REPORT_DB_HOST
valueFrom:
configMapKeyRef:
key: "reportdb_host"
name: uyuni-config
optional: false
- name: REPORT_DB_PORT
valueFrom:
configMapKeyRef:
key: "reportdb_port"
name: uyuni-config
optional: false
- name: REPORT_DB_NAME
valueFrom:
configMapKeyRef:
key: "reportdb_name"
name: uyuni-config
optional: false
- name: REPORT_DB_USER
valueFrom:
secretKeyRef:
key: username
name: reportdb-credentials
optional: false
image: {{ include "uyuni.image" (dict "name" "server" "global" . "local" .Values.server) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: db-waiter
volumes:
- name: var-cobbler
persistentVolumeClaim:
claimName: var-cobbler
- name: var-search
persistentVolumeClaim:
claimName: var-search
- name: var-salt
persistentVolumeClaim:
claimName: var-salt
- name: var-cache
persistentVolumeClaim:
claimName: var-cache
- name: var-spacewalk
persistentVolumeClaim:
claimName: var-spacewalk
- name: var-log
persistentVolumeClaim:
claimName: var-log
- name: srv-salt
persistentVolumeClaim:
claimName: srv-salt
- name: srv-www
persistentVolumeClaim:
claimName: srv-www
- name: srv-tftpboot
persistentVolumeClaim:
claimName: srv-tftpboot
- name: srv-formulametadata
persistentVolumeClaim:
claimName: srv-formulametadata
- name: srv-pillar
persistentVolumeClaim:
claimName: srv-pillar
- name: srv-susemanager
persistentVolumeClaim:
claimName: srv-susemanager
- name: srv-spacewalk
persistentVolumeClaim:
claimName: srv-spacewalk
- name: ca-certs
persistentVolumeClaim:
claimName: ca-certs
- name: run-salt-master
persistentVolumeClaim:
claimName: run-salt-master
- name: etc-apache2
persistentVolumeClaim:
claimName: etc-apache2
- name: etc-systemd-multi
persistentVolumeClaim:
claimName: etc-systemd-multi
- name: etc-systemd-sockets
persistentVolumeClaim:
claimName: etc-systemd-sockets
- name: etc-salt
persistentVolumeClaim:
claimName: etc-salt
- name: etc-tomcat
persistentVolumeClaim:
claimName: etc-tomcat
- name: etc-cobbler
persistentVolumeClaim:
claimName: etc-cobbler
- name: etc-sysconfig
persistentVolumeClaim:
claimName: etc-sysconfig
- name: etc-postfix
persistentVolumeClaim:
claimName: etc-postfix
- name: etc-sssd
persistentVolumeClaim:
claimName: etc-sssd
- name: etc-rhn
persistentVolumeClaim:
claimName: etc-rhn
- configMap:
defaultMode: 420
name: uyuni-ca
name: ca-cert
- configMap:
defaultMode: 420
name: db-ca
name: db-ca-cert
- name: tls
secret:
defaultMode: 420
items:
- key: tls.crt
path: tls/certs/spacewalk.crt
- key: tls.key
mode: 256
path: tls/private/spacewalk.key
secretName: uyuni-cert
- emptyDir:
medium: Memory
sizeLimit: 256Mi
name: run
- name: sys-fs-cgroup
emptyDir:
{{- if .Values.server.mirror }}
{{- if .Values.server.mirror.claimName }}
- name: mirror
persistentVolumeClaim:
claimName: {{ .Values.server.mirror.claimName }}
{{- else if .Values.server.mirror.hostPath }}
- name: mirror
hostPath:
path: {{ .Values.server.mirror.hostPath }}
{{- end }}
{{- end }}
{{- if .Values.server.extraVolumes }}
{{ toYaml .Values.server.extraVolumes | nindent 6 }}
{{- end }}

View file

@ -0,0 +1,293 @@
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: cobbler
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: cobbler
port: 25151
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: ClusterIP
{{- if .Values.db.enable }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
name: db
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: pgsql
port: 5432
selector:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
name: reportdb
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.reportdb.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.reportdb.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: pgsql
port: 5432
{{- if eq (default .Values.services.type .Values.services.reportdb.type) "NodePort" }}
nodePort: {{ .Values.services.reportdb.ports.pgsql }}
{{- end }}
selector:
app.kubernetes.io/component: db
app.kubernetes.io/part-of: uyuni
type: {{ .Values.services.reportdb.type | default .Values.services.type }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: salt
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.salt.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.salt.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: publish
port: 4505
{{- if eq (default .Values.services.type .Values.services.salt.type) "NodePort" }}
nodePort: {{ .Values.services.salt.ports.publish }}
{{- end }}
- name: request
port: 4506
{{- if eq (default .Values.services.type .Values.services.salt.type) "NodePort" }}
nodePort: {{ .Values.services.salt.ports.request }}
{{- end }}
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: {{ .Values.services.salt.type | default .Values.services.type }}
---
{{- if .Values.exposeJavaDebug | default false }}
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: search
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.search.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.search.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: debug
port: 8002
{{- if eq (default .Values.services.type .Values.services.search.type) "NodePort" }}
nodePort: {{ .Values.services.search.ports.debug }}
{{- end }}
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: {{ .Values.services.search.type | default .Values.services.type }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: taskomatic
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.taskomatic.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.taskomatic.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: debug
port: 8001
{{- if eq (default .Values.services.type .Values.services.taskomatic.type) "NodePort" }}
nodePort: {{ .Values.services.taskomatic.ports.debug }}
{{- end }}
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: {{ .Values.services.taskomatic.type | default .Values.services.type }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: tomcat
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.tomcat.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.tomcat.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: debug
port: 8003
{{- if eq (default .Values.services.type .Values.services.tomcat.type) "NodePort" }}
nodePort: {{ .Values.services.tomcat.ports.debug }}
{{- end }}
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: {{ .Values.services.tomcat.type | default .Values.services.type }}
---
{{- end }}
{{- if ne .Values.enableMonitoring false }}
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: taskomatic-internal
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: jmx
port: 5557
- name: mtrx
port: 9800
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: ClusterIP
---
{{- end }}
{{- if and .Values.tftp.enable (not .Values.tftp.hostNetwork) }}
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: tftp
app.kubernetes.io/part-of: uyuni
name: tftp
namespace: "{{ .Release.Namespace }}"
{{- if or .Values.services.annotations .Values.services.tftp.annotations }}
annotations:
{{ toYaml ( mergeOverwrite (dict) (default (dict) .Values.services.annotations) (default (dict) .Values.services.tftp.annotations) ) | indent 4 }}
{{- end }}
spec:
ports:
- name: tftp
port: 69
protocol: UDP
targetPort: 69
selector:
app.kubernetes.io/component: tftp
app.kubernetes.io/part-of: uyuni
# ClusterIP or NodePort wouldn't work for TFTP if not using the host network
type: LoadBalancer
# Ensures all packets from a single client go to the same pod
sessionAffinity: ClientIP
# Preserves the client's source IP and avoids extra hops between nodes
externalTrafficPolicy: Local
---
{{- end }}
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: tomcat-internal
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: node-exporter
port: 9100
{{- if ne .Values.enableMonitoring false }}
- name: jmx
port: 5556
- name: pgsql-exporter
port: 9187
{{- end }}
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
name: web
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app.kubernetes.io/component: server
app.kubernetes.io/part-of: uyuni
type: ClusterIP
{{- if default .Values.hubAPI.enable false }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: hub-xmlrpc
app.kubernetes.io/part-of: uyuni
name: hub-xmlrpc
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: hub
port: 2830
selector:
app.kubernetes.io/component: hub-xmlrpc
app.kubernetes.io/part-of: uyuni
type: ClusterIP
{{- end }}
{{- if default .Values.saline.enable false }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: saline
app.kubernetes.io/part-of: uyuni
name: saline
namespace: "{{ .Release.Namespace }}"
spec:
ports:
- name: saline
port: 8216
selector:
app.kubernetes.io/component: saline
app.kubernetes.io/part-of: uyuni
type: ClusterIP
{{- end }}

View file

@ -0,0 +1,110 @@
{{- if .Values.gateway.enable }}
{{- $gatewayName := .Values.gateway.name | default "uyuni-gateway" -}}
{{- if ne (default .Values.services.type .Values.services.salt.type) "NodePort" }}
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: salt-publish
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: salt-publish
rules:
- backendRefs:
- name: salt
port: 4505
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: salt-request
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: salt-request
rules:
- backendRefs:
- name: salt
port: 4506
{{- end }}
{{- if and .Values.db.enable (ne (default .Values.services.type .Values.services.reportdb.type) "NodePort") }}
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: reportdb-pgsql
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: reportdb-pgsql
rules:
- backendRefs:
- name: reportdb
port: 5432
{{- end }}
{{- if .Values.exposeJavaDebug }}
{{- if ne (default .Values.services.type .Values.services.taskomatic.type) "NodePort" }}
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: tasko-debug
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: tasko-debug
rules:
- backendRefs:
- name: taskomatic
port: 8001
{{- end }}
{{- if ne (default .Values.services.type .Values.services.search.type) "NodePort" }}
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: search-debug
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: search-debug
rules:
- backendRefs:
- name: search
port: 8002
{{- end }}
{{- if ne (default .Values.services.type .Values.services.tomcat.type) "NodePort" }}
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: tomcat-debug
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
parentRefs:
- name: {{ $gatewayName }}
sectionName: tomcat-debug
rules:
- backendRefs:
- name: tomcat
port: 8003
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,57 @@
{{- if .Values.tftp.enable }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: tftp
app.kubernetes.io/part-of: uyuni
name: tftp
namespace: "{{ .Release.Namespace }}"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: tftp
app.kubernetes.io/part-of: uyuni
template:
metadata:
labels:
app.kubernetes.io/component: tftp
app.kubernetes.io/part-of: uyuni
spec:
{{- include "uyuni.nodePlacement" (dict "global" .Values.placement "local" .Values.tftp) | nindent 6 }}
{{- if .Values.tftp.hostNetwork }}
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
{{- end }}
containers:
- name: tftp
image: {{ include "uyuni.image" (dict "name" "proxy-tftpd" "global" . "local" .Values.tftp) }}
imagePullPolicy: {{ .Values.pullPolicy }}
command:
- /usr/bin/tftp_wrapper.py
- --httpHost
- web.{{ .Release.Namespace }}.svc
- --proxyFqdn
- {{ .Values.global.fqdn }}
- --serverFqdn
- {{ .Values.global.fqdn }}
ports:
- containerPort: 69
protocol: UDP
{{- if .Values.registrySecret }}
imagePullSecrets:
- name: {{ .Values.registrySecret }}
{{- end }}
initContainers:
- command:
- sh
- -c
- |2
until curl -L http://web/rhn/manager/api/api/getVersion; do
sleep 60
done
image: {{ include "uyuni.image" (dict "name" "proxy-tftpd" "global" . "local" .Values.tftp) }}
imagePullPolicy: {{ .Values.pullPolicy }}
name: server-waiter
{{- end }}

View file

@ -0,0 +1,150 @@
{{- if and (not .Values.gateway.enable) (eq ((.Values.ingress).type) "traefik") }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: uyuni-https-redirect
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
spec:
redirectScheme:
scheme: https
permanent: true
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: uyuni-strip-prefixes
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/part-of: uyuni
spec:
stripPrefix:
prefixes:
- /postgresql-exporter
- /node-exporter
- /tasko-exporter
- /tasko-jmx
- /tomcat-jmx
- /saline
{{- if ne (default .Values.services.type .Values.services.reportdb.type) "NodePort" }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: reportdb-pgsql-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- reportdb-pgsql
routes:
- match: HostSNI(`*`)
services:
- name: reportdb
port: 5432
{{- end }}
{{- if ne (default .Values.services.type .Values.services.salt.type) "NodePort" }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: salt-publish-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- salt-publish
routes:
- match: HostSNI(`*`)
services:
- name: salt
port: 4505
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: salt-request-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- salt-request
routes:
- match: HostSNI(`*`)
services:
- name: salt
port: 4506
{{- end }}
{{- if .Values.exposeJavaDebug }}
{{- if ne (default .Values.services.type .Values.services.taskomatic.type) "NodePort" }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: tomcat-debug-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- tomcat-debug
routes:
- match: HostSNI(`*`)
services:
- name: tomcat
port: 8003
{{- end }}
{{- if ne (default .Values.services.type .Values.services.search.type) "NodePort" }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: search-debug-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- search-debug
routes:
- match: HostSNI(`*`)
services:
- name: search
port: 8002
{{- end }}
{{- if ne (default .Values.services.type .Values.services.tomcat.type) "NodePort" }}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: tasko-debug-route
namespace: "{{ .Release.Namespace }}"
labels:
app.kubernetes.io/part-of: uyuni
annotations:
kubernetes.io/ingress.class: {{ .Values.ingress.class }}
spec:
entryPoints:
- tasko-debug
routes:
- match: HostSNI(`*`)
services:
- name: taskomatic
port: 8001
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,19 @@
#!/bin/sh
# Requires to install helm unittest plugin:
# helm plugin install --verify=false https://github.com/helm-unittest/helm-unittest
helm unittest .
# Requires to install kubeconform:
# zypper in kubeconform
# The remote schema location is to validate the Traefik CRDs.
helm template . --set global.fqdn=test.local --set hubAPI.enable=true --set coco.replicas=3 --set saline.enable=true | \
kubeconform -summary -strict \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'
# Check the API Gateway resources
helm template . --set global.fqdn=test.local --set hubAPI.enable=true --set coco.replicas=3 --set saline.enable=true --set gateway.enable=true --set gateway.class=gw | \
kubeconform -summary -strict \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'

View file

@ -0,0 +1,3 @@
[buildconfig]
builder = custom.ChartBuilder
tagger = tito.tagger.SUSEContainerTagger

View file

@ -0,0 +1,451 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"title": "Values",
"type": "object",
"required": [
"global",
"repository"
],
"properties": {
"repository": {
"type": "string",
"description": "The default repository for images",
"default": "registry.opensuse.org/uyuni"
},
"tag": {
"type": "string",
"description": "The default tag to use for images",
"default": "latest"
},
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"],
"default": "IfNotPresent"
},
"registrySecret": {
"type": "string",
"description": "Name of the secret which contains the credentials for the registry",
"default": ""
},
"timezone": {
"type": "string",
"description": "The time zone to set in the containers",
"default": "Etc/UTC"
},
"placement": {
"$ref": "#/definitions/nodeSelectorConfig",
"description": "Default node placement rules for all pods"
},
"global": {
"type": "object",
"required": [
"fqdn"
],
"properties": {
"fqdn": {
"type": "string",
"description": "The fully qualified domain name the server will answer to"
}
}
},
"server": {
"type": ["object", "null"],
"description": "configuration of the server component",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"email": {
"type": "string",
"description": "Email address for notifications sent by the server",
"default": "admin@uyuni.lab.org"
},
"superPrivileged": {
"type": "boolean",
"description": "Run the server container with super privileges, bypassing a lot of selinux or AppArmor checks. This is dangerous!",
"default": false
},
"apparmorProfile": {
"type": "string",
"description": "appArmor profile is the name of an AppArmor profile to use for the server pod."
},
"selinuxType": {
"type": "string",
"description": "SELinux type is the name of the SELinux type to use for the server pod."
},
"systemdLogLevel": {
"type": "string",
"enum": ["debug", "info", "notice", "warning", "err", "crit", "alert", "emerg", ""],
"description": "Value passed to systemd's --log-level parameter, can be useful for debugging"
},
"mirror": {
"type": "object",
"description": "Defines a volume or host path to mount as server.susemanager.fromdir",
"properties": {
"claimName": {
"type": "string"
},
"hostPath": {
"type": "string"
}
}
},
"extraVolumes": {
"type": ["array", "null"],
"description": "Additional Kubernetes volumes for the server pod",
"items": {
"type": "object"
}
},
"extraVolumeMounts": {
"type": ["array", "null"],
"description": "Additional volume mounts for the server container",
"items": {
"type": "object"
}
},
"sccSecret": {
"type": "string",
"description": "the name of a basic-auth secret with the organization mirroring credentials to set up on the server.",
"default": ""
}
}
},
"tftp": {
"type": ["object", "null"],
"description": "configuration of the tftp server component",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"hostNetwork": {
"type": "boolean",
"description": "Use the host network instead of Kubernetes network infrastructure",
"default": false
},
"enable": {
"type": "boolean",
"description": "Deploy the TFTP server to PXE boot systems",
"default": true
}
}
},
"volumes": {
"type": "object",
"description": "Defines the volume claims for the server components",
"properties": {
"storageClass": {
"type": ["string", "null"],
"description": "default storage class to use for the volume claims"
},
"var-pgsql": { "$ref": "#/definitions/volumeConfig" },
"var-spacewalk": { "$ref": "#/definitions/volumeConfig" },
"var-cache": { "$ref": "#/definitions/volumeConfig" },
"var-log": { "$ref": "#/definitions/volumeConfig" },
"srv-www": { "$ref": "#/definitions/volumeConfig" },
"srv-tftpboot": { "$ref": "#/definitions/volumeConfig" },
"ca-certs": { "$ref": "#/definitions/volumeConfig" },
"etc-apache2": { "$ref": "#/definitions/volumeConfig" },
"etc-cobbler": { "$ref": "#/definitions/volumeConfig" },
"etc-postfix": { "$ref": "#/definitions/volumeConfig" },
"etc-rhn": { "$ref": "#/definitions/volumeConfig" },
"etc-salt": { "$ref": "#/definitions/volumeConfig" },
"etc-sssd": { "$ref": "#/definitions/volumeConfig" },
"etc-sysconfig": { "$ref": "#/definitions/volumeConfig" },
"etc-systemd-multi": { "$ref": "#/definitions/volumeConfig" },
"etc-systemd-sockets": { "$ref": "#/definitions/volumeConfig" },
"etc-tomcat": { "$ref": "#/definitions/volumeConfig" },
"run-salt-master": { "$ref": "#/definitions/volumeConfig" },
"srv-formulametadata": { "$ref": "#/definitions/volumeConfig" },
"srv-pillar": { "$ref": "#/definitions/volumeConfig" },
"srv-salt": { "$ref": "#/definitions/volumeConfig" },
"srv-spacewalk": { "$ref": "#/definitions/volumeConfig" },
"srv-susemanager": { "$ref": "#/definitions/volumeConfig" },
"var-cobbler": { "$ref": "#/definitions/volumeConfig" },
"var-salt": { "$ref": "#/definitions/volumeConfig" },
"var-search": { "$ref": "#/definitions/volumeConfig" }
}
},
"services": {
"type": ["object"],
"description": "Services tuning properties",
"properties": {
"type": {
"type": "string",
"description": "type of all the externally-facing services. Can be overridden on each service",
"enum": ["ClusterIP", "NodePort", "LoadBalancer"],
"default": "ClusterIP"
},
"annotations": {
"type": ["object", "null"],
"description": "annotations to set to all the services. Merged with the service ones."
},
"reportdb": {
"$ref": "#/definitions/serviceConfig",
"description": "values for the reportdb service. The ports keys can only be pgsql (5432)"
},
"salt": {
"$ref": "#/definitions/serviceConfig",
"description": "values for the salt master service. The ports keys can be one of 'publish' (4505) or 'request' (4506)"
},
"search": {
"$ref": "#/definitions/serviceConfig",
"description": "values for the search server service. The ports keys can only be debug (8002)"
},
"taskomatic": {
"$ref": "#/definitions/serviceConfig",
"description": "values for the taskomatic service. The ports keys can only be debug (8001)"
},
"tomcat": {
"$ref": "#/definitions/serviceConfig",
"description": "values for the tomcat service. The ports keys can only be debug (8003)"
},
"tftp": {
"type": ["object", "null"],
"description": "values for the tomcat service. Changing the service type doesn't make sense for TFTP",
"properties": {
"annotations": {
"type": ["object", "null"],
"description": "annotations to set to the service. This can be helpful to configure a load balancer"
}
}
}
}
},
"exposeJavaDebug": {
"type": "boolean",
"description": "Expose ports 8001, 8002, and 8003 for Java debugging",
"default": false
},
"enableMonitoring": {
"type": "boolean",
"description": "Expose metrics ports for Prometheus scraping",
"default": true
},
"ingress": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Type of ingress used (supported values: traefik, '')",
"enum": ["traefik", ""],
"default": "traefik"
},
"class": {
"type": "string",
"description": "Name of the ingress class to use. This value will be used in traefik routes annotations.",
"default": "traefik"
},
"annotations": {
"type": "object",
"description": "Custom annotations for ingress rules",
"properties": {
"ssl": { "type": "object" },
"sslRedirect": { "type": "object" },
"nossl": { "type": "object" },
"saline": { "type": "object" },
"hub": { "type": "object" },
"exporters": { "type": "object" }
}
}
}
},
"gateway": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the gateway to use. An empty string value means that a gateway will be deployed and named uyuni-gateway.",
"default": ""
},
"class": {
"type": "string",
"description": "Name of the gateway class to use. For rke2 with traefik, it is likely to be 'traefik'.",
"default": ""
},
"listeners": {
"type": "object",
"description": "Gateway listeners configuration",
"properties": {
"http": {
"$ref": "#/definitions/listener",
"description": "Configuration of the HTTP listener. Defaults are adjusted to traefik on rke2"
},
"https": {
"$ref": "#/definitions/listener",
"description": "Configuration of the HTTPS listener. Defaults are adjusted to traefik on rke2"
}
}
}
}
},
"hubAPI": {
"type": ["object", "null"],
"description": "configuration of the hub API component",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"enable": {
"type": "boolean",
"description": "Enable or disable the Hub XML-RPC API deployment",
"default": false
}
}
},
"coco": {
"type": ["object", "null"],
"description": "configuration of the confidential computing attestation component",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"replicas": {
"type": "integer",
"description": "Number of replicas for confidential computing attestation",
"minimum": 0,
"default": 0
}
}
},
"saline": {
"type": ["object", "null"],
"description": "configuration of the saline component",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"enable": {
"type": "boolean",
"description": "Deploy Saline for salt master monitoring",
"default": false
}
}
},
"db": {
"type": ["object", "null"],
"description": "configuration of the PostgreSQL database",
"allOf": [
{ "$ref": "#/definitions/imageConfig" },
{ "$ref": "#/definitions/nodeSelectorConfig" }
],
"properties": {
"enable": {
"type": "boolean",
"description": "Deploy a PostgreSQL instance.",
"default": true
},
"internal": { "ref": "#/definitions/dbConnectionConfig" },
"report": { "ref": "#/definitions/dbConnectionConfig" }
}
}
},
"definitions": {
"nodeSelectorConfig": {
"type": ["object", "null"],
"properties": {
"nodeSelector": { "type": ["object", "null"], "description": "Node label matching rules." },
"affinity": { "type": ["object", "null"], "description": "Advanced scheduling rules." },
"tolerations": { "type": ["array", "null"], "description": "Node taint tolerations." },
"nodeName": { "type": ["string", "null"], "description": "Specific node assignment." }
}
},
"imageConfig": {
"type": ["object", "null"],
"properties": {
"image": {
"type": ["string", "null"],
"description": "The image full URL without tag"
},
"tag": {
"type": ["string", "null"],
"description": "The image tag"
}
}
},
"dbConnectionConfig": {
"type": ["object", "null"],
"properties": {
"host": {
"type": ["string", "null"],
"description": "FQDN to use to connect to the database"
},
"port": {
"type": ["integer", "null"],
"description": "port to use to connect to the database",
"default": 5432
},
"name": {
"type": ["string", "null"],
"description": "Postgresql database name to connect to"
}
}
},
"volumeConfig": {
"type": "object",
"properties": {
"size": {
"type": "string",
"description": "Requested volume size"
},
"storageClass": {
"type": ["string", "null"],
"description": "storage class to use for the volume claim"
},
"extraLabels": {
"type": ["object", "null"],
"description": "labels to add to the volume claim"
},
"annotations": {
"type": ["object", "null"],
"description": "annotations to set to the volume claim"
},
"volumeName": {
"type": ["string", "null"],
"description": "volume to force binding to if set"
},
"selector": {
"type": ["object", "null"],
"description": "selector to set on the volume claim"
}
}
},
"serviceConfig": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Type of service to define",
"enum": ["ClusterIP", "NodePort", "LoadBalancer", ""],
"default": ""
},
"ports": {
"type": "object",
"description": "Ports to expose by the service when using the NodePort type. Values need to match the port name of the service"
},
"annotations": {
"type": ["object", "null"],
"description": "annotations to set to the service. This can be helpful to configure a load balancer"
}
}
},
"listener": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "the name of the listener"
},
"port": {
"type": "integer",
"description": "the port of the listener"
}
}
}
}
}

View file

@ -0,0 +1,952 @@
# The default repository with the path where to find all the images.
repository: registry.opensuse.org/uyuni
# The default tag to use for images, can be overridden for each image.
tag: latest
# Ref: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
pullPolicy: "IfNotPresent"
# registrySecret defines the name of secret to use to pull the images from the
# registry with authentication. Leave empty for no authentication.
#
# To create the secret, see:
# https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
registrySecret: ""
# The time zone to set in the containers
timezone: "Etc/UTC"
# Server component configuration
server:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# Email will be the email used for the notifications sent by the server.
email: "admin@uyuni.lab.org"
# sccSecret is the name of a basic-auth secret with the organization mirroring credentials to set up on the server.
sccSecret: ""
# mirror defines a volume or host path to mount in the container as server.susemanager.fromdir value.
# Use either claimName or hostPath to reference the volume source.
#
# If the value is set before the first run of the server, the rhn.conf file will be adjusted during the setup.
mirror:
# claimName is the name of the PVC to use for the mirror volume.
# When using set, both the claim and the PV need to be defined before running the chart.
claimName: ""
# hostPath is the path on the node to mount as mirror.
# Using this is strongly discouraged as it is tied to where the server runs.
hostPath: ""
# extraVolumes defines additional Kubernetes volumes for the server pod.
# This can be used to mount operator-managed volumes without modifying the chart templates.
extraVolumes: []
# extraVolumeMounts defines additional mounts for the server container.
# Every entry must reference a volume from server.extraVolumes or another
# volume already defined in the pod.
extraVolumeMounts: []
# superPrivileged may need to be set to true to run on a cluster with selinux or AppArmor enforced.
# This is only for the server pod, since it runs systemd.
# Setting this to true opens a big security can of worms.
superPrivileged: false
# systemdLogLevel will be passed to systemd's --log-level parameter.
# Note, that this will add a tty to the container.
# The possible values are debug, info, notice, warning, err, crit, alert, emerg or "" to keep the default.
systemdLogLevel: ""
# appArmor profile is the name of an AppArmor profile to use for the server pod.
# The profile need to be showing up in the aa-status command output.
apparmorProfile: ""
# SELinux type is the name of the SELinux type to use for the server pod.
# By default, it's not set so the container runtime's default (typically container_t) is used,
# or spc_t if superPrivileged is enabled.
selinuxType: ""
global:
# fqdn is the fully qualified name the server will answer as.
# Changing this value renames the server and changes the server FQDN in the database, handle with care.
# This value is required.
fqdn:
# Services tuning properties.
services:
# type of all the externally-facing services. Can be overridden on each service.
# Ref: https://kubernetes.io/docs/concepts/services-networking/service/
type: ClusterIP
# annotations to set to all the services. Merged with the service ones.
annotations:
# Values setting up the reportdb service.
reportdb:
# Type of service to define, overriding the global setting
type: ""
# Ports to expose by the service when using the NodePort type.
ports:
# postgresql port to expose, usually known as port 5432.
pgsql: 30032
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# Values setting up the salt service.
salt:
# Type of service to define, overriding the global setting
type: ""
# Ports to expose by the service when using the NodePort type.
ports:
# Salt publish port, usually known as port 4505
publish: 30005
# Salt request port, usually known as port 4506
request: 30006
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# Values setting up the search server service.
# This is only for debugging purpose.
search:
# Type of service to define, overriding the global setting
type: ""
# Ports to expose by the service when using the NodePort type.
ports:
# Java debug port, usually known as port 8002
debug: 30002
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# Values setting up the taskomatic service.
# This is only for debugging purpose.
taskomatic:
# Type of service to define, overriding the global setting
type: ""
# Ports to expose by the service when using the NodePort type.
ports:
# Java debug port, usually known as port 8001
debug: 30001
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# Values setting up the tomcat service.
# This is only for debugging purpose.
tomcat:
# Type of service to define, overriding the global setting
type: ""
# Ports to expose by the service when using the NodePort type.
ports:
# Java debug port, usually known as port 8003
debug: 30003
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# Values setting up the tftp service.
# This service can only set annotations: changing the type doesn't make sense.
tftp:
# Annotations to set on the service.
# This can be useful to configure a load balancer for example.
annotations:
# exposeJavaDebug will expose the 8001, 8002 and 8003 ports to connect a Java debugger
# to taskomatic, search server and tomcat respectively
exposeJavaDebug: false
# enableMonitoring will create the ingress or gateway routes for the prometheus exporters.
enableMonitoring: true
ingress:
# ingress.type defines the ingress that is used in the cluster.
# It can be "traefik" or any other value.
type: "traefik"
# Specify the ingress class name to use. Empty, means that the default one will be used.
# If using the traefik end points and TCP routers, this value needs to match Traefik's
# --providers.kubernetescrd.ingressclass parameter's value.
# On rke2 this is likely to be "traefik". On K3S it is likely to be ""
class: "traefik"
# annotations can be used to set custom annotations on the created ingress rules.
# This can be used to configure another ingress than the ones already wired with the ingress.type.
# The ssl annotations can also be used to set a cert-manager issuer like:
# ingress:
# annotations:
# ssl:
# cert-manager.io/cluster-issuer: uyuniIssuer
annotations:
# ssl holds the annotations for the main ssl ingress.
ssl: {}
# sslRedirect holds the annotations for the ssl redirect ingress.
# This ingress is only created if the ingress type is set to 'traefik'.
sslRedirect: {}
# nossl holds the annotations for the HTTP ingress.
nossl: {}
# saline holds the annotations for the saline ssl ingress.
saline: {}
# hub holds the annotations for the hub API ssl ingress.
hub: {}
# exporters holds the annotations for the prometheus exporters SSL ingress.
exporters: {}
# Gateway configures the Gateway API.
gateway:
# If enabled, Gateway API 1.4 resources will be deployed instead of the ingress ones.
# Note that TCPRoute is used and is still in alpha2 stage.
enable: false
# Name of the gateway class to use. For rke2 with traefik, it is likely to be "traefik".
class: ""
# Name of the gateway to use. An empty string value means that a gateway will be deployed and named uyuni-gateway.
name: ""
listeners:
http:
# Name to set for the gateway http listener. The default is adjusted for traefik on rke2
name: "web"
# Port to set for the gateway http listener. The default is adjusted for traefik on rke2
port: 8000
https:
# Name to set for the gateway https listener. The default is adjusted for traefik on rke2
name: "websecure"
# Port to set for the gateway https listener. The default is adjusted for traefik on rke2
port: 8443
# TFTP server configuration
tftp:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# enable or disable the TFTP server.
enable: false
# Use the host network to bypass the Kubernetes network layers.
# This may be needed if not using a LoadBalancer for the TFTP server.
# Note that this may be more complex to manage on multi-node clusters.
hostNetwork: false
# hub API component configuration
hubAPI:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# enable or disable the Hub XML-RPC API deployment.
enable: false
# Confidential computing attestation component configuration
coco:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# number of replicas for the confidential computing attestation deployment.
replicas: 0
# Saline component configuration
saline:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# set to true to deploy saline and provide salt master metrics
enable: false
# PostgreSQL database configuration
db:
# image overrides the default image computed using the repository property
# Leave undefined to use the default
image:
# tag overrides the default tag in the tag property
# Leave undefined to use the default
tag:
# enable to deploy a PostgreSQL instance.
# WARNING: using a third party database is not tested and supported for now.
enable: true
# Configuration of the internal database connection
# WARNING: Only taken into account if db is disabled
internal:
# Host name to use for the internal database.
# It should be added to the SANs of the database TLS certificate
host:
# Port to use to connect to the internal database
port: 5432
# Name of the postgresql database to connect to
name:
# Configuration of the report database connection
# WARNING: Only taken into account if db is disabled
report:
# Host name to use for the report database.
# It should be added to the SANs of the database TLS certificate
host:
# Port to use to connect to the internal database
port: 5432
# Name of the postgresql database to connect to
name:
# Configuration of the persistent volume claims.
volumes:
# Default storage class name to use for all the claims
storageClass:
# var-pgsql is the volume for the database,
# a fast and big enough persistent volume will be needed.
var-pgsql:
# size is the requested volume size.
# The size of the postgresql data volume needs to be at least 50Gi.
# This value is required.
size: 50Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# var-spacewalk contains the synchronized packages and needs to be sized depending on the distributions to manage.
var-spacewalk:
# size is the requested volume size.
# See https://www.uyuni-project.org/uyuni-docs/en/uyuni/installation-and-upgrade/uyuni-install-requirements.html
# how to estimate the size depending on the distributions.
# This value is required.
size: 100Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# var-cache is the volume holding the cache for the server.
var-cache:
# size is the requested volume size.
# See https://www.uyuni-project.org/uyuni-docs/en/uyuni/installation-and-upgrade/uyuni-install-requirements.html
# how to estimate the size.
# This value is required.
size: 10Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# var-log is the volume holding the log files for the server pod.
var-log:
# size is the requested volume size.
# This value is required.
size: 2Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# srv-www is the volume containing the files published over HTTP.
# This also includes the unpacked auto-installation distribution ISOs.
srv-www:
# size is the requested volume size.
# Take into account the number and size of the distributions unpacked ISO images to use for auto-installation.
# This value is required.
size: 100Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
srv-tftpboot:
# size is the requested volume size.
# This value is required.
size: 300Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
ca-certs:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-apache2:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-cobbler:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-postfix:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-rhn:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-salt:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-sssd:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-sysconfig:
# size is the requested volume size.
# This value is required.
size: 20Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-systemd-multi:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-systemd-sockets:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
etc-tomcat:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
run-salt-master:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# srv-formulametadata contains the custom Salt Formulas metadata.
srv-formulametadata:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# srv-pillar contains the custom Salt pillar.
srv-pillar:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
# srv-salt contains the custom Salt states.
srv-salt:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
srv-spacewalk:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
srv-susemanager:
# size is the requested volume size.
# This value is required.
size: 1Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
var-cobbler:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
var-salt:
# size is the requested volume size.
# This value is required.
size: 10Mi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector:
var-search:
# size is the requested volume size.
# This value is required.
size: 10Gi
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default storage class.
storageClass:
# extraLabels adds custom labels to the PVC metadata
extraLabels:
# annotations sets annotations to the PVC.
# This may be useful to configure some storage backends
annotations:
# volumeName sets the volumeName to bind to if defined.
volumeName:
# selector is rendered with toYAML and can be used to bind to a specific PV.
selector: