1
0
forked from suse-edge/Factory

unpack obscpio files

This commit is contained in:
Denislav Prodanov 2024-10-22 10:51:51 +03:00
parent beab68c274
commit 21086b77bb
182 changed files with 15763 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,2 @@
Verify that all CDI components are installed correctly:
kubectl get all -n {{ .Release.Namespace }}

View File

@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "cdi.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "cdi.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "cdi.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "cdi.labels" -}}
helm.sh/chart: {{ include "cdi.chart" . }}
{{ include "cdi.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "cdi.selectorLabels" -}}
app.kubernetes.io/name: {{ include "cdi.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "cdi.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "cdi.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,47 @@
{{/* Hook annotations */}}
{{- define "cdi.hook.annotations" -}}
annotations:
"helm.sh/hook": {{ .hookType }}
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
"helm.sh/hook-weight": {{ .hookWeight | quote }}
{{- end -}}
{{/* Namespace modifying hook annotations */}}
{{- define "cdi.namespaceHook.annotations" -}}
{{ template "cdi.hook.annotations" merge (dict "hookType" "pre-install") . }}
{{- end -}}
{{/* CRD upgrading hook annotations */}}
{{- define "cdi.crdUpgradeHook.annotations" -}}
{{ template "cdi.hook.annotations" merge (dict "hookType" "pre-upgrade") . }}
{{- end -}}
{{/* Custom resource uninstalling hook annotations */}}
{{- define "cdi.crUninstallHook.annotations" -}}
{{ template "cdi.hook.annotations" merge (dict "hookType" "pre-delete") . }}
{{- end -}}
{{/* CRD uninstalling hook annotations */}}
{{- define "cdi.crdUninstallHook.annotations" -}}
{{ template "cdi.hook.annotations" merge (dict "hookType" "post-delete") . }}
{{- end -}}
{{/* Namespace modifying hook name */}}
{{- define "cdi.namespaceHook.name" -}}
{{ include "cdi.fullname" . }}-namespace-modify
{{- end }}
{{/* CRD upgrading hook name */}}
{{- define "cdi.crdUpgradeHook.name" -}}
{{ include "cdi.fullname" . }}-crd-upgrade
{{- end }}
{{/* Custom resource uninstalling hook name */}}
{{- define "cdi.crUninstallHook.name" -}}
{{ include "cdi.fullname" . }}-uninstall
{{- end }}
{{/* CRD uninstalling hook name */}}
{{- define "cdi.crdUninstallHook.name" -}}
{{ include "cdi.fullname" . }}-crd-uninstall
{{- end }}

View File

@ -0,0 +1,671 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
operator.cdi.kubevirt.io: ""
name: cdi-operator-cluster
rules:
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterrolebindings
- clusterroles
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
- customresourcedefinitions/status
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- cdi.kubevirt.io
- upload.cdi.kubevirt.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
- mutatingwebhookconfigurations
verbs:
- create
- list
- watch
- apiGroups:
- admissionregistration.k8s.io
resourceNames:
- cdi-api-dataimportcron-validate
- cdi-api-populator-validate
- cdi-api-datavolume-validate
- cdi-api-validate
- objecttransfer-api-validate
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
- delete
- apiGroups:
- admissionregistration.k8s.io
resourceNames:
- cdi-api-datavolume-mutate
- cdi-api-pvc-mutate
resources:
- mutatingwebhookconfigurations
verbs:
- get
- update
- delete
- apiGroups:
- apiregistration.k8s.io
resources:
- apiservices
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- watch
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshots
verbs:
- get
- list
- watch
- apiGroups:
- cdi.kubevirt.io
resources:
- datavolumes
verbs:
- list
- get
- apiGroups:
- cdi.kubevirt.io
resources:
- datasources
verbs:
- get
- apiGroups:
- cdi.kubevirt.io
resources:
- volumeclonesources
verbs:
- get
- list
- watch
- apiGroups:
- cdi.kubevirt.io
resources:
- storageprofiles
verbs:
- get
- list
- watch
- apiGroups:
- cdi.kubevirt.io
resources:
- cdis
verbs:
- get
- list
- watch
- apiGroups:
- cdi.kubevirt.io
resources:
- cdiconfigs
verbs:
- get
- list
- watch
- apiGroups:
- cdi.kubevirt.io
resources:
- cdis/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- create
- update
- delete
- deletecollection
- patch
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- persistentvolumeclaims/finalizers
- pods/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- pods
- services
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- create
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
- csidrivers
verbs:
- get
- list
- watch
- apiGroups:
- config.openshift.io
resources:
- proxies
- infrastructures
verbs:
- get
- list
- watch
- apiGroups:
- config.openshift.io
resources:
- clusterversions
verbs:
- get
- apiGroups:
- cdi.kubevirt.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshots
- volumesnapshotclasses
- volumesnapshotcontents
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshots
verbs:
- update
- deletecollection
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- apiGroups:
- scheduling.k8s.io
resources:
- priorityclasses
verbs:
- get
- list
- watch
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- apiGroups:
- kubevirt.io
resources:
- virtualmachines/finalizers
verbs:
- update
- apiGroups:
- forklift.cdi.kubevirt.io
resources:
- ovirtvolumepopulators
- openstackvolumepopulators
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- apiGroups:
- cdi.kubevirt.io
resources:
- dataimportcrons
verbs:
- get
- list
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
operator.cdi.kubevirt.io: ""
name: cdi-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cdi-operator-cluster
subjects:
- kind: ServiceAccount
name: cdi-operator
namespace: {{ .Release.Namespace }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
operator.cdi.kubevirt.io: ""
name: cdi-operator
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app: containerized-data-importer
app.kubernetes.io/component: storage
app.kubernetes.io/managed-by: cdi-operator
cdi.kubevirt.io: ""
name: cdi-operator
namespace: {{ .Release.Namespace }}
rules:
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- ""
resources:
- serviceaccounts
- configmaps
- events
- secrets
- services
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- apps
resources:
- deployments
- deployments/finalizers
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- route.openshift.io
resources:
- routes
- routes/custom-host
verbs:
- get
- list
- watch
- create
- update
- apiGroups:
- config.openshift.io
resources:
- proxies
verbs:
- get
- list
- watch
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
- prometheusrules
verbs:
- get
- list
- watch
- create
- delete
- update
- patch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- create
- update
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- get
- list
- watch
- create
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- delete
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
verbs:
- get
- list
- watch
- create
- update
- deletecollection
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- deletecollection
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- create
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: containerized-data-importer
app.kubernetes.io/component: storage
app.kubernetes.io/managed-by: cdi-operator
cdi.kubevirt.io: ""
name: cdi-operator
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: cdi-operator
subjects:
- kind: ServiceAccount
name: cdi-operator
namespace: {{ .Release.Namespace }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
cdi.kubevirt.io: cdi-operator
name: cdi-operator
operator.cdi.kubevirt.io: ""
prometheus.cdi.kubevirt.io: "true"
name: cdi-operator
namespace: {{ .Release.Namespace }}
spec:
replicas: 1
selector:
matchLabels:
name: cdi-operator
operator.cdi.kubevirt.io: ""
strategy: {}
template:
metadata:
labels:
cdi.kubevirt.io: cdi-operator
name: cdi-operator
operator.cdi.kubevirt.io: ""
prometheus.cdi.kubevirt.io: "true"
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: cdi.kubevirt.io
operator: In
values:
- cdi-operator
topologyKey: kubernetes.io/hostname
weight: 1
containers:
- env:
- name: DEPLOY_CLUSTER_RESOURCES
value: "true"
- name: OPERATOR_VERSION
value: {{ .Values.deployment.version }}
- name: CONTROLLER_IMAGE
value: {{ .Values.deployment.controllerImage }}:{{ .Values.deployment.version }}
- name: IMPORTER_IMAGE
value: {{ .Values.deployment.importerImage }}:{{ .Values.deployment.version }}
- name: CLONER_IMAGE
value: {{ .Values.deployment.clonerImage }}:{{ .Values.deployment.version }}
- name: OVIRT_POPULATOR_IMAGE
value: {{ .Values.deployment.importerImage }}:{{ .Values.deployment.version }}
- name: APISERVER_IMAGE
value: {{ .Values.deployment.apiserverImage }}:{{ .Values.deployment.version }}
- name: UPLOAD_SERVER_IMAGE
value: {{ .Values.deployment.uploadserverImage }}:{{ .Values.deployment.version }}
- name: UPLOAD_PROXY_IMAGE
value: {{ .Values.deployment.uploadproxyImage }}:{{ .Values.deployment.version }}
- name: VERBOSITY
value: "1"
- name: PULL_POLICY
value: {{ .Values.deployment.pullPolicy }}
- name: MONITORING_NAMESPACE
image: {{ .Values.deployment.operatorImage }}:{{ .Values.deployment.version }}
imagePullPolicy: {{ .Values.deployment.pullPolicy }}
name: cdi-operator
ports:
- containerPort: 8080
name: metrics
protocol: TCP
resources:
requests:
cpu: 100m
memory: 150Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
serviceAccountName: cdi-operator
tolerations:
- key: CriticalAddonsOnly
operator: Exists

View File

@ -0,0 +1,69 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crUninstallHook.name" . }}
{{ template "cdi.crUninstallHook.annotations" (dict "hookWeight" 1) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "cdi.crUninstallHook.name" . }}
{{ template "cdi.crUninstallHook.annotations" (dict "hookWeight" 1) }}
rules:
- apiGroups: [ "cdi.kubevirt.io" ]
resources: [ "cdis" ]
resourceNames:
- "cdi"
verbs: [ "delete" ]
- apiGroups: [ "apps" ]
resources: [ "deployments" ]
verbs: [ "get", "list" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "cdi.crUninstallHook.name" . }}
{{ template "cdi.crUninstallHook.annotations" (dict "hookWeight" 2) }}
subjects:
- kind: ServiceAccount
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crUninstallHook.name" . }}
roleRef:
kind: ClusterRole
name: {{ template "cdi.crUninstallHook.name" . }}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crUninstallHook.name" . }}
{{ template "cdi.crUninstallHook.annotations" (dict "hookWeight" 3) }}
spec:
template:
metadata:
name: {{ template "cdi.crUninstallHook.name" . }}
spec:
serviceAccountName: {{ template "cdi.crUninstallHook.name" . }}
restartPolicy: {{ .Values.hookRestartPolicy }}
containers:
- name: {{ template "cdi.crUninstallHook.name" . }}
image: {{ .Values.hookImage }}
securityContext:
{{- toYaml .Values.hookSecurityContext | nindent 12 }}
args:
- delete
- cdi
- cdi
- name: {{ template "cdi.crUninstallHook.name" . }}-cleanup
image: {{ .Values.hookImage }}
securityContext:
{{- toYaml .Values.hookSecurityContext | nindent 12 }}
args:
- wait
- --for=delete
- deployments/cdi-apiserver
- deployments/cdi-deployment
- deployments/cdi-uploadproxy
- --timeout=60s

View File

@ -0,0 +1,21 @@
apiVersion: cdi.kubevirt.io/v1beta1
kind: CDI
metadata:
name: cdi
spec:
{{- with .Values.cdi.config }}
config:
{{- toYaml . | nindent 4 }}
{{- end }}
imagePullPolicy: {{ .Values.cdi.imagePullPolicy }}
{{- with .Values.cdi.infra }}
infra:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.cdi.uninstallStrategy }}
uninstallStrategy: {{ .Values.cdi.uninstallStrategy }}
{{- end }}
{{- with .Values.cdi.workload }}
workload:
{{- toYaml . | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,55 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUninstallHook.name" . }}
{{ template "cdi.crdUninstallHook.annotations" (dict "hookWeight" 1) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "cdi.crdUninstallHook.name" . }}
{{ template "cdi.crdUninstallHook.annotations" (dict "hookWeight" 1) }}
rules:
- apiGroups: [ "apiextensions.k8s.io" ]
resources: [ "customresourcedefinitions" ]
resourceNames:
- "cdis.cdi.kubevirt.io"
verbs: [ "delete" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "cdi.crdUninstallHook.name" . }}
{{ template "cdi.crdUninstallHook.annotations" (dict "hookWeight" 2) }}
subjects:
- kind: ServiceAccount
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUninstallHook.name" . }}
roleRef:
kind: ClusterRole
name: {{ template "cdi.crdUninstallHook.name" . }}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUninstallHook.name" . }}
{{ template "cdi.crdUninstallHook.annotations" (dict "hookWeight" 3) }}
spec:
template:
metadata:
name: {{ template "cdi.crdUninstallHook.name" . }}
spec:
serviceAccountName: {{ template "cdi.crdUninstallHook.name" . }}
restartPolicy: {{ .Values.hookRestartPolicy }}
containers:
- name: {{ template "cdi.crdUninstallHook.name" . }}
image: {{ .Values.hookImage }}
args:
- delete
- customresourcedefinitions
- cdis.cdi.kubevirt.io
securityContext:
{{- toYaml .Values.hookSecurityContext | nindent 12 }}

View File

@ -0,0 +1,80 @@
apiVersion: v1
kind: ConfigMap
metadata:
namespace: {{ .Release.Namespace }}
name: cdi-crd-manifest
{{ template "cdi.crdUpgradeHook.annotations" (dict "hookWeight" 1) }}
data:
crd: |-
{{ $.Files.Get "crds/cdi.yaml" | nindent 4 }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUpgradeHook.name" . }}
{{ template "cdi.crdUpgradeHook.annotations" (dict "hookWeight" 2) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "cdi.crdUpgradeHook.name" . }}
{{ template "cdi.crdUpgradeHook.annotations" (dict "hookWeight" 2) }}
rules:
- apiGroups: [ "" ]
resources: [ "configmaps" ]
resourceNames:
- "cdi-crd-manifest"
verbs: [ "get" ]
- apiGroups: [ "apiextensions.k8s.io" ]
resources: [ "customresourcedefinitions" ]
resourceNames:
- "cdis.cdi.kubevirt.io"
verbs: [ "get", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "cdi.crdUpgradeHook.name" . }}
{{ template "cdi.crdUpgradeHook.annotations" (dict "hookWeight" 3) }}
subjects:
- kind: ServiceAccount
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUpgradeHook.name" . }}
roleRef:
kind: ClusterRole
name: {{ template "cdi.crdUpgradeHook.name" . }}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.crdUpgradeHook.name" . }}
{{ template "cdi.crdUpgradeHook.annotations" (dict "hookWeight" 4) }}
spec:
template:
metadata:
name: {{ template "cdi.crdUpgradeHook.name" . }}
spec:
serviceAccountName: {{ template "cdi.crdUpgradeHook.name" . }}
restartPolicy: {{ .Values.hookRestartPolicy }}
containers:
- name: {{ template "cdi.crdUpgradeHook.name" . }}
image: {{ .Values.hookImage }}
args:
- apply
- -f
- /etc/manifests/crd.yaml
securityContext:
{{- toYaml .Values.hookSecurityContext | nindent 12 }}
volumeMounts:
- name: crd-volume
mountPath: /etc/manifests
volumes:
- name: crd-volume
configMap:
name: cdi-crd-manifest
items:
- key: crd
path: crd.yaml

View File

@ -0,0 +1,56 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.namespaceHook.name" . }}
{{ template "cdi.namespaceHook.annotations" (dict "hookWeight" 1) }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "cdi.namespaceHook.name" . }}
{{ template "cdi.namespaceHook.annotations" (dict "hookWeight" 1) }}
rules:
- apiGroups: [ "" ]
resources: [ "namespaces" ]
resourceNames:
- {{ .Release.Namespace | quote }}
verbs: [ "get", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "cdi.namespaceHook.name" . }}
{{ template "cdi.namespaceHook.annotations" (dict "hookWeight" 2) }}
subjects:
- kind: ServiceAccount
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.namespaceHook.name" . }}
roleRef:
kind: ClusterRole
name: {{ template "cdi.namespaceHook.name" . }}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: {{ .Release.Namespace }}
name: {{ template "cdi.namespaceHook.name" . }}
{{ template "cdi.namespaceHook.annotations" (dict "hookWeight" 3) }}
spec:
template:
metadata:
name: {{ template "cdi.namespaceHook.name" . }}
spec:
serviceAccountName: {{ template "cdi.namespaceHook.name" . }}
restartPolicy: {{ .Values.hookRestartPolicy }}
containers:
- name: {{ template "cdi.namespaceHook.name" . }}
securityContext:
{{- toYaml .Values.hookSecurityContext | nindent 12 }}
image: {{ .Values.hookImage }}
args:
- label
- namespace
- {{ .Release.Namespace }}
- cdi.kubevirt.io=

Binary file not shown.

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 0.6.1
description: A Helm chart for baremetal-operator, used by Metal3
name: baremetal-operator
type: application
version: 0.5.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
labels:
clusterctl.cluster.x-k8s.io: ""
name: bmceventsubscriptions.metal3.io
spec:
group: metal3.io
names:
kind: BMCEventSubscription
listKind: BMCEventSubscriptionList
plural: bmceventsubscriptions
shortNames:
- bes
- bmcevent
singular: bmceventsubscription
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: The most recent error message
jsonPath: .status.error
name: Error
type: string
- description: Time duration since creation of BMCEventSubscription
jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: BMCEventSubscription is the Schema for the fast eventing API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
context:
description: Arbitrary user-provided context for the event
type: string
destination:
description: A webhook URL to send events to
type: string
hostName:
description: A reference to a BareMetalHost
type: string
httpHeadersRef:
description: A secret containing HTTP headers which should be passed
along to the Destination when making a request
properties:
name:
description: name is unique within a namespace to reference a
secret resource.
type: string
namespace:
description: namespace defines the space within which the secret
name must be unique.
type: string
type: object
x-kubernetes-map-type: atomic
type: object
status:
properties:
error:
type: string
subscriptionID:
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,75 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
name: dataimages.metal3.io
spec:
group: metal3.io
names:
kind: DataImage
listKind: DataImageList
plural: dataimages
singular: dataimage
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: DataImage is the Schema for the dataimages API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: DataImageSpec defines the desired state of DataImage.
properties:
url:
description: Url is the address of the dataImage that we want to attach
to a BareMetalHost
type: string
required:
- url
type: object
status:
description: DataImageStatus defines the observed state of DataImage.
properties:
attachedImage:
description: Currently attached DataImage
properties:
url:
type: string
required:
- url
type: object
error:
description: Error count and message when attaching/detaching
properties:
count:
type: integer
message:
type: string
required:
- count
- message
type: object
lastReconciled:
description: Time of last reconciliation
format: date-time
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,90 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
labels:
clusterctl.cluster.x-k8s.io: ""
name: firmwareschemas.metal3.io
spec:
group: metal3.io
names:
kind: FirmwareSchema
listKind: FirmwareSchemaList
plural: firmwareschemas
singular: firmwareschema
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: FirmwareSchema is the Schema for the firmwareschemas API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: FirmwareSchemaSpec defines the desired state of FirmwareSchema.
properties:
hardwareModel:
description: The hardware model associated with this schema
type: string
hardwareVendor:
description: The hardware vendor associated with this schema
type: string
schema:
additionalProperties:
description: Additional data describing the firmware setting.
properties:
allowable_values:
description: The allowable value for an Enumeration type setting.
items:
type: string
type: array
attribute_type:
description: The type of setting.
enum:
- Enumeration
- String
- Integer
- Boolean
- Password
type: string
lower_bound:
description: The lowest value for an Integer type setting.
type: integer
max_length:
description: Maximum length for a String type setting.
type: integer
min_length:
description: Minimum length for a String type setting.
type: integer
read_only:
description: Whether or not this setting is read only.
type: boolean
unique:
description: Whether or not this setting's value is unique to
this node, e.g. a serial number.
type: boolean
upper_bound:
description: The highest value for an Integer type setting.
type: integer
type: object
description: Map of firmware name to schema
type: object
required:
- schema
type: object
type: object
served: true
storage: true

View File

@ -0,0 +1,211 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
labels:
clusterctl.cluster.x-k8s.io: ""
name: hardwaredata.metal3.io
spec:
group: metal3.io
names:
kind: HardwareData
listKind: HardwareDataList
plural: hardwaredata
shortNames:
- hd
singular: hardwaredata
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Time duration since creation of HardwareData
jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: HardwareData is the Schema for the hardwaredata API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: HardwareDataSpec defines the desired state of HardwareData.
properties:
hardware:
description: The hardware discovered on the host during its inspection.
properties:
cpu:
description: CPU describes one processor on the host.
properties:
arch:
type: string
clockMegahertz:
description: ClockSpeed is a clock speed in MHz
format: double
type: number
count:
type: integer
flags:
items:
type: string
type: array
model:
type: string
type: object
firmware:
description: Firmware describes the firmware on the host.
properties:
bios:
description: The BIOS for this firmware
properties:
date:
description: The release/build date for this BIOS
type: string
vendor:
description: The vendor name for this BIOS
type: string
version:
description: The version of the BIOS
type: string
type: object
type: object
hostname:
type: string
nics:
items:
description: NIC describes one network interface on the host.
properties:
ip:
description: The IP address of the interface. This will
be an IPv4 or IPv6 address if one is present. If both
IPv4 and IPv6 addresses are present in a dual-stack environment,
two nics will be output, one with each IP.
type: string
mac:
description: The device MAC address
pattern: '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'
type: string
model:
description: The vendor and product IDs of the NIC, e.g.
"0x8086 0x1572"
type: string
name:
description: The name of the network interface, e.g. "en0"
type: string
pxe:
description: Whether the NIC is PXE Bootable
type: boolean
speedGbps:
description: The speed of the device in Gigabits per second
type: integer
vlanId:
description: The untagged VLAN ID
format: int32
maximum: 4094
minimum: 0
type: integer
vlans:
description: The VLANs available
items:
description: VLAN represents the name and ID of a VLAN.
properties:
id:
description: VLANID is a 12-bit 802.1Q VLAN identifier
format: int32
maximum: 4094
minimum: 0
type: integer
name:
type: string
type: object
type: array
type: object
type: array
ramMebibytes:
type: integer
storage:
items:
description: Storage describes one storage device (disk, SSD,
etc.) on the host.
properties:
alternateNames:
description: A list of alternate Linux device names of the
disk, e.g. "/dev/sda". Note that this list is not exhaustive,
and names may not be stable across reboots.
items:
type: string
type: array
hctl:
description: The SCSI location of the device
type: string
model:
description: Hardware model
type: string
name:
description: A Linux device name of the disk, e.g. "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0".
This will be a name that is stable across reboots if one
is available.
type: string
rotational:
description: Whether this disk represents rotational storage.
This field is not recommended for usage, please prefer
using 'Type' field instead, this field will be deprecated
eventually.
type: boolean
serialNumber:
description: The serial number of the device
type: string
sizeBytes:
description: The size of the disk in Bytes
format: int64
type: integer
type:
description: 'Device type, one of: HDD, SSD, NVME.'
enum:
- HDD
- SSD
- NVME
type: string
vendor:
description: The name of the vendor of the device
type: string
wwn:
description: The WWN of the device
type: string
wwnVendorExtension:
description: The WWN Vendor extension of the device
type: string
wwnWithExtension:
description: The WWN with the extension
type: string
type: object
type: array
systemVendor:
description: HardwareSystemVendor stores details about the whole
hardware system.
properties:
manufacturer:
type: string
productName:
type: string
serialNumber:
type: string
type: object
type: object
type: object
type: object
served: true
storage: true
subresources: {}

View File

@ -0,0 +1,178 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
name: hostfirmwarecomponents.metal3.io
spec:
group: metal3.io
names:
kind: HostFirmwareComponents
listKind: HostFirmwareComponentsList
plural: hostfirmwarecomponents
singular: hostfirmwarecomponents
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: HostFirmwareComponents is the Schema for the hostfirmwarecomponents
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: HostFirmwareComponentsSpec defines the desired state of HostFirmwareComponents.
properties:
updates:
items:
description: FirmwareUpdate defines a firmware update specification.
properties:
component:
type: string
url:
type: string
required:
- component
- url
type: object
type: array
required:
- updates
type: object
status:
description: HostFirmwareComponentsStatus defines the observed state of
HostFirmwareComponents.
properties:
components:
description: Components is the list of all available firmware components
and their information.
items:
description: FirmwareComponentStatus defines the status of a firmware
component.
properties:
component:
type: string
currentVersion:
type: string
initialVersion:
type: string
lastVersionFlashed:
type: string
updatedAt:
format: date-time
type: string
required:
- component
- initialVersion
type: object
type: array
conditions:
description: Track whether updates stored in the spec are valid based
on the schema
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
lastUpdated:
description: Time that the status was last updated
format: date-time
type: string
updates:
description: Updates is the list of all firmware components that should
be updated they are specified via name and url fields.
items:
description: FirmwareUpdate defines a firmware update specification.
properties:
component:
type: string
url:
type: string
required:
- component
- url
type: object
type: array
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,164 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
labels:
clusterctl.cluster.x-k8s.io: ""
name: hostfirmwaresettings.metal3.io
spec:
group: metal3.io
names:
kind: HostFirmwareSettings
listKind: HostFirmwareSettingsList
plural: hostfirmwaresettings
shortNames:
- hfs
singular: hostfirmwaresettings
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: HostFirmwareSettings is the Schema for the hostfirmwaresettings
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: HostFirmwareSettingsSpec defines the desired state of HostFirmwareSettings.
properties:
settings:
additionalProperties:
anyOf:
- type: integer
- type: string
x-kubernetes-int-or-string: true
description: Settings are the desired firmware settings stored as
name/value pairs.
type: object
required:
- settings
type: object
status:
description: HostFirmwareSettingsStatus defines the observed state of
HostFirmwareSettings.
properties:
conditions:
description: Track whether settings stored in the spec are valid based
on the schema
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
lastUpdated:
description: Time that the status was last updated
format: date-time
type: string
schema:
description: FirmwareSchema is a reference to the Schema used to describe
each FirmwareSetting. By default, this will be a Schema in the same
Namespace as the settings but it can be overwritten in the Spec
properties:
name:
description: '`name` is the reference to the schema.'
type: string
namespace:
description: '`namespace` is the namespace of the where the schema
is stored.'
type: string
required:
- name
- namespace
type: object
settings:
additionalProperties:
type: string
description: Settings are the firmware settings stored as name/value
pairs
type: object
required:
- settings
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,183 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.1
labels:
clusterctl.cluster.x-k8s.io: ""
name: preprovisioningimages.metal3.io
spec:
group: metal3.io
names:
kind: PreprovisioningImage
listKind: PreprovisioningImageList
plural: preprovisioningimages
shortNames:
- ppimg
singular: preprovisioningimage
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Whether the image is ready
jsonPath: .status.conditions[?(@.type=='Ready')].status
name: Ready
type: string
- description: The reason for the image readiness status
jsonPath: .status.conditions[?(@.type=='Ready')].reason
name: Reason
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: PreprovisioningImage is the Schema for the preprovisioningimages
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: PreprovisioningImageSpec defines the desired state of PreprovisioningImage.
properties:
acceptFormats:
description: acceptFormats is a list of acceptable image formats.
items:
description: ImageFormat enumerates the allowed image formats
enum:
- iso
- initrd
type: string
type: array
architecture:
description: architecture is the processor architecture for which
to build the image.
type: string
networkDataName:
description: networkDataName is the name of a Secret in the local
namespace that contains network data to build in to the image.
type: string
type: object
status:
description: PreprovisioningImageStatus defines the observed state of
PreprovisioningImage.
properties:
architecture:
description: architecture is the processor architecture for which
the image is built
type: string
conditions:
description: conditions describe the state of the built image
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
extraKernelParams:
description: extraKernelParams is a string with extra parameters to
pass to the kernel when booting the image over network. Only makes
sense for initrd images.
type: string
format:
description: 'format is the type of image that is available at the
download url: either iso or initrd.'
enum:
- iso
- initrd
type: string
imageUrl:
description: imageUrl is the URL from which the built image can be
downloaded.
type: string
kernelUrl:
description: kernelUrl is the URL from which the kernel of the image
can be downloaded. Only makes sense for initrd images.
type: string
networkData:
description: networkData is a reference to the version of the Secret
containing the network data used to build the image.
properties:
name:
type: string
version:
type: string
type: object
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,16 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "baremetal-operator.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "baremetal-operator.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "baremetal-operator.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "baremetal-operator.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -0,0 +1,63 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "baremetal-operator.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "baremetal-operator.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "baremetal-operator.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "baremetal-operator.labels" -}}
helm.sh/chart: {{ include "baremetal-operator.chart" . }}
{{ include "baremetal-operator.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "baremetal-operator.selectorLabels" -}}
app.kubernetes.io/component: baremetal-operator
app.kubernetes.io/name: {{ include "baremetal-operator.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "baremetal-operator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "baremetal-operator.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ include "baremetal-operator.fullname" . }}-serving-cert
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
spec:
dnsNames:
- baremetal-operator-webhook-service.{{ .Release.Namespace }}.svc
- baremetal-operator-webhook-service.{{ .Release.Namespace }}.svc.cluster.local
issuerRef:
kind: Issuer
name: {{ include "baremetal-operator.fullname" . }}-selfsigned-issuer
secretName: bmo-webhook-server-cert

View File

@ -0,0 +1,186 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: {{ include "baremetal-operator.fullname" . }}-manager-role
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- update
- watch
- apiGroups:
- metal3.io
resources:
- baremetalhosts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- baremetalhosts/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- bmceventsubscriptions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- bmceventsubscriptions/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- firmwareschemas
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- firmwareschemas/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- hardware/finalizers
verbs:
- update
- apiGroups:
- metal3.io
resources:
- hardwaredata
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- hostfirmwaresettings
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- hostfirmwaresettings/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- preprovisioningimages
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- preprovisioningimages/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- dataimages
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- dataimages/status
verbs:
- get
- patch
- update
- apiGroups:
- metal3.io
resources:
- hostfirmwarecomponents
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal3.io
resources:
- hostfirmwarecomponents/status
verbs:
- get
- patch
- update

View File

@ -0,0 +1,11 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "baremetal-operator.fullname" . }}-metrics-reader
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
rules:
- nonResourceURLs:
- /metrics
verbs:
- get

View File

@ -0,0 +1,19 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "baremetal-operator.fullname" . }}-proxy-role
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create

View File

@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "baremetal-operator.fullname" . }}-manager-rolebinding
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "baremetal-operator.fullname" . }}-manager-role
subjects:
- kind: ServiceAccount
name: {{ include "baremetal-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "baremetal-operator.fullname" . }}-proxy-rolebinding
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "baremetal-operator.fullname" . }}-proxy-role
subjects:
- kind: ServiceAccount
name: {{ include "baremetal-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,30 @@
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}
{{- $protocol := ternary "https" "http" $enableTLS }}
{{- $ironicIP := .Values.global.ironicIP | default "" }}
{{- $ironicApiHost := print $ironicIP ":6385" }}
{{- $ironicInspectorHost := print $ironicIP ":5050" }}
{{- $ironicBootHost := print $ironicIP ":6180" }}
{{- $ironicCacheHost := print $ironicIP ":6180" }}
apiVersion: v1
data:
IRONIC_ENDPOINT: "{{ $protocol }}://{{ $ironicApiHost }}/v1/"
IRONIC_INSPECTOR_ENDPOINT: "{{ $protocol }}://{{ $ironicInspectorHost }}/v1/"
RESTART_CONTAINER_CERTIFICATE_UPDATED: "false"
# Switch VMedia to HTTP if enable_vmedia_tls is false
{{- if and $enableTLS $enableVMediaTLS }}
{{- $ironicBootHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $ironicCacheHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $protocol = "https" }}
{{- else }}
{{- $protocol = "http" }}
{{- end }}
CACHEURL: "{{ $protocol }}://{{ $ironicCacheHost }}/images"
DEPLOY_KERNEL_URL: "{{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent.kernel"
DEPLOY_RAMDISK_URL: "{{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent.initramfs"
kind: ConfigMap
metadata:
name: baremetal-operator-ironic
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}

View File

@ -0,0 +1,19 @@
apiVersion: v1
data:
controller_manager_config.yaml: |
apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
health:
healthProbeBindAddress: :9440
metrics:
bindAddress: 127.0.0.1:8085
webhook:
port: 9443
leaderElection:
leaderElect: true
resourceName: a9498140.metal3.io
kind: ConfigMap
metadata:
name: baremetal-operator-manager-config
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}

View File

@ -0,0 +1,131 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
control-plane: controller-manager
webhook: metal3-io-v1alpha1-baremetalhost
name: {{ include "baremetal-operator.fullname" . }}-controller-manager
spec:
minReadySeconds: 10
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "baremetal-operator.selectorLabels" . | nindent 6 }}
control-plane: controller-manager
template:
metadata:
labels:
{{- include "baremetal-operator.selectorLabels" . | nindent 8 }}
control-plane: controller-manager
webhook: metal3-io-v1alpha1-baremetalhost
spec:
containers:
- args:
- --metrics-addr=127.0.0.1:8085
- --enable-leader-election
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
envFrom:
- configMapRef:
name: {{ include "baremetal-operator.fullname" . }}-ironic
image: "{{ .Values.images.baremetalOperator.repository }}:{{ .Values.images.baremetalOperator.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.images.baremetalOperator.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
livenessProbe:
failureThreshold: 10
httpGet:
path: /healthz
port: 9440
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
readinessProbe:
failureThreshold: 10
httpGet:
path: /readyz
port: 9440
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
{{- if .Values.global.enable_basicAuth }}
- name: ironic-basic-auth
mountPath: "/opt/metal3/auth/ironic/username"
subPath: username
readOnly: true
- name: ironic-basic-auth
mountPath: "/opt/metal3/auth/ironic/password"
subPath: password
readOnly: true
- name: ironic-inspector-basic-auth
mountPath: "/opt/metal3/auth/ironic-inspector/username"
subPath: username
readOnly: true
- name: ironic-inspector-basic-auth
mountPath: "/opt/metal3/auth/ironic-inspector/password"
subPath: password
readOnly: true
{{- end }}
{{- if .Values.global.enable_tls }}
- name: cacert
mountPath: "/opt/metal3/certs/ca"
readOnly: true
{{- end }}
- args:
- --secure-listen-address=0.0.0.0:8443
- --upstream=http://127.0.0.1:8085/
- --logtostderr=true
- --v=10
image: "{{ .Values.images.rbacProxy.repository }}:{{ .Values.images.rbacProxy.tag }}"
imagePullPolicy: {{ .Values.images.rbacProxy.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
serviceAccountName: {{ include "baremetal-operator.serviceAccountName" . }}
terminationGracePeriodSeconds: 10
volumes:
- name: cert
secret:
defaultMode: 420
secretName: bmo-webhook-server-cert
{{- if .Values.global.enable_basicAuth }}
- name: ironic-basic-auth
secret:
secretName: ironic-basic-auth
- name: ironic-inspector-basic-auth
secret:
secretName: ironic-inspector-basic-auth
{{- end }}
{{- if .Values.global.enable_tls }}
- name: cacert
secret:
secretName: ironic-cacert
{{- end }}
{{- with .Values.global.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,8 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
name: {{ include "baremetal-operator.fullname" . }}-selfsigned-issuer
spec:
selfSigned: {}

View File

@ -0,0 +1,45 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "baremetal-operator.fullname" . }}-leader-election-role
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- configmaps/status
verbs:
- get
- update
- patch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete

View File

@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "baremetal-operator.fullname" . }}-leader-election-rolebinding
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "baremetal-operator.fullname" . }}-leader-election-role
subjects:
- kind: ServiceAccount
name: {{ include "baremetal-operator.serviceAccountName" . }}

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
control-plane: controller-manager
name: {{ include "baremetal-operator.fullname" . }}-controller-manager-metrics-service
spec:
ports:
- name: https
port: 8443
targetPort: https
selector:
control-plane: controller-manager

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
name: {{ include "baremetal-operator.fullname" . }}-webhook-service
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
webhook: metal3-io-v1alpha1-baremetalhost

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "baremetal-operator.serviceAccountName" . }}
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "baremetal-operator.fullname" . }}-test-connection"
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "baremetal-operator.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@ -0,0 +1,51 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
{{- include "baremetal-operator.labels" . | nindent 4 }}
annotations:
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "baremetal-operator.fullname" . }}-serving-cert
name: {{ include "baremetal-operator.fullname" . }}-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
- v1beta
clientConfig:
service:
name: {{ include "baremetal-operator.fullname" . }}-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metal3-io-v1alpha1-baremetalhost
failurePolicy: Fail
name: baremetalhost.metal3.io
rules:
- apiGroups:
- metal3.io
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- baremetalhosts
sideEffects: None
- admissionReviewVersions:
- v1
- v1beta
clientConfig:
service:
name: {{ include "baremetal-operator.fullname" . }}-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metal3-io-v1alpha1-bmceventsubscription
failurePolicy: Fail
name: bmceventsubscription.metal3.io
rules:
- apiGroups:
- metal3.io
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- bmceventsubscriptions
sideEffects: None

View File

@ -0,0 +1,90 @@
# Default values for baremetal-operator.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
# specify comma serparate beginning and end of the range of IP
# addresses the DHCP server will manage.
dhcpRange: 192.168.20.20,192.168.20.80
# Network interface on which provisioning network can be accessed
provisioningInterface: ens4
# IP Address assigned to network interface on provisioning network
provisioningIP: 192.168.20.5
# If running in a multi-node kubernetes cluster, "pin" the baremtal container
# to the same host where the ironic and media containers
# arerunning. Uncomment the nodeSelector and update the hostname accordingly.
#nodeSelector:
#kubernetes.io/hostname: "my-hostname"
# Comment this out when pinning the baremetal-operator container to a specfic host.
nodeSelector: {}
replicaCount: 1
images:
baremetalOperator:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/baremetal-operator
pullPolicy: IfNotPresent
tag: "0.6.1"
rbacProxy:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/kube-rbac-proxy
pullPolicy: IfNotPresent
tag: "v0.14.2"
imagePullSecrets: []
nameOverride: "manger"
fullnameOverride: "baremetal-operator"
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: "baremetal-operator-controller-manager"
podAnnotations: {}
securityContext:
runAsUser: 11000
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
runAsNonRoot: true
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
tolerations: []
affinity: {}
baremetaloperator:
httpPort: "6180"

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 24.1.2
description: A Helm chart for Ironic, used by Metal3
name: ironic
type: application
version: 0.7.0

View File

@ -0,0 +1,24 @@
## How to Enable Provisioning Network
By default PXE boot functionality is disabled, so deployments via e.g redfish-virtualmedia may
be performed without any dedicated provisioning network.
For PXE boot a dedicated network is required, in this case we run a dnsmasq instance to provide
DHCP and require a dedicated NIC for connectivity to the provisioning network on each host.
To enable this mode you must provide the following additional configuration (note the values are
examples and will depend on your environment):
```
global:
enable_dnsmasq: true
enable_pxe_boot: true
dnsmasqDefaultRouter: 192.168.21.254
dnsmasqDNSServer: 192.168.20.5
dhcpRange: 192.168.20.20,192.168.20.80
provisioningInterface: ens4
provisioningIP: 192.168.20.5
```
Note that these values *must not* conflict with your controlplane or other networks otherwise unexpected
behavior is likely - a dedicated physical network is required in this configuration.

View File

@ -0,0 +1,16 @@
1. Get the application URL by running these commands:
{{- if eq .Values.service.type "NodePort" }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "ironic.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if eq .Values.service.type "LoadBalancer" }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "ironic.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "ironic.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:6385
{{- else if eq .Values.service.type "ClusterIP" }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "ironic.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -0,0 +1,88 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "ironic.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "ironic.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "ironic.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "ironic.labels" -}}
helm.sh/chart: {{ include "ironic.chart" . }}
{{ include "ironic.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "ironic.selectorLabels" -}}
app.kubernetes.io/component: ironic
app.kubernetes.io/name: {{ include "ironic.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "ironic.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "ironic.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Shared directory volumeMount
*/}}
{{- define "ironic.sharedVolumeMount" -}}
- mountPath: /shared
name: ironic-data-volume
{{- end }}
{{/*
Get ironic CA volumeMounts
*/}}
{{- define "ironic.CAVolumeMounts" -}}
- name: cert-ironic-ca
mountPath: "/certs/ca/ironic"
readOnly: true
- name: cert-ironic-inspector-ca
mountPath: "/certs/ca/ironic-inspector"
readOnly: true
{{- if .Values.global.enable_vmedia_tls }}
- name: cert-ironic-vmedia-ca
mountPath: "/certs/ca/vmedia"
readOnly: true
{{- end }}
{{- end }}

View File

@ -0,0 +1,56 @@
{{- if .Values.global.enable_tls -}}
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-cacert
spec:
commonName: ironic-ca
isCA: true
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: ironic-cacert
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-cert
spec:
commonName: ironic-cert
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: ca-issuer
secretName: ironic-cert
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-inspector-cert
spec:
commonName: ironic-inspector-cert
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: ca-issuer
secretName: ironic-inspector-cert
{{- if .Values.global.enable_vmedia_tls }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ironic-vmedia-cert
spec:
commonName: ironic-vmedia-cert
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: ca-issuer
secretName: ironic-vmedia-cert
{{- end }}
{{- end }}

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: ironic-ipa-downloader
labels:
{{- include "ironic.labels" . | nindent 4 }}
data:
{{- with .Values.baremetaloperator }}
{{ if .ipaBaseUri }}
IPA_BASEURI: {{ .ipaBaseUri }}
{{ end }}
{{ end }}

View File

@ -0,0 +1,86 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: ironic-bmo
labels:
{{- include "ironic.labels" . | nindent 4 }}
data:
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}
{{- $protocol := ternary "https" "http" $enableTLS }}
{{- $ironicIP := .Values.global.ironicIP | default "" }}
{{- $ironicApiHost := print $ironicIP ":6385" }}
{{- $ironicInspectorHost := print $ironicIP ":5050" }}
{{- $ironicBootHost := print $ironicIP ":6180" }}
{{- $ironicCacheHost := print $ironicIP ":6180" }}
{{- if ( .Values.global.enable_dnsmasq ) }}
DNSMASQ_BOOT_SERVER_ADDRESS: {{ $ironicBootHost }}
DNSMASQ_DNS_SERVER_ADDRESS: {{ .Values.global.dnsmasqDNSServer }}
DNSMASQ_DEFAULT_ROUTER: {{ .Values.global.dnsmasqDefaultRouter }}
DHCP_RANGE: {{ .Values.global.dhcpRange }}
{{- end }}
{{- if .Values.debug.ironicRamdiskSshKey }}
IRONIC_RAMDISK_SSH_KEY: {{ .Values.debug.ironicRamdiskSshKey }}
{{- end }}
HTTP_PORT: "6180"
PREDICTABLE_NIC_NAMES: "{{ .Values.global.predictableNicNames }}"
USE_IRONIC_INSPECTOR: "true"
IRONIC_API_BASE_URL: {{ $protocol }}://{{ $ironicApiHost }}
IRONIC_API_HOST: {{ $ironicApiHost }}
IRONIC_API_HTTPD_SERVER_NAME: {{ $ironicApiHost }}
IRONIC_ENDPOINT: {{ $protocol }}://{{ $ironicApiHost }}/v1/
IRONIC_INSPECTOR_BASE_URL: {{ $protocol }}://{{ $ironicInspectorHost }}
IRONIC_INSPECTOR_ENDPOINT: {{ $protocol }}://{{ $ironicInspectorHost }}/v1/
IRONIC_INSPECTOR_HOST: {{ $ironicInspectorHost }}
IRONIC_INSPECTOR_HTTPD_SERVER_NAME: {{ $ironicInspectorHost }}
# Switch VMedia to HTTP if enable_vmedia_tls is false
{{- if and $enableTLS $enableVMediaTLS }}
{{- $ironicBootHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $ironicCacheHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $protocol = "https" }}
{{- else }}
{{- $protocol = "http" }}
{{- end }}
IRONIC_EXTERNAL_HTTP_URL: {{ $protocol }}://{{ $ironicCacheHost }}
CACHEURL: {{ $protocol }}://{{ $ironicCacheHost }}/images
DEPLOY_KERNEL_URL: {{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent.kernel
DEPLOY_RAMDISK_URL: {{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent.initramfs
IRONIC_BOOT_BASE_URL: {{ $protocol }}://{{ $ironicBootHost }}
IRONIC_VMEDIA_HTTPD_SERVER_NAME: {{ $ironicBootHost }}
ENABLE_PXE_BOOT: "{{ .Values.global.enable_pxe_boot }}"
{{- if .Values.global.provisioningInterface }}
PROVISIONING_INTERFACE: {{ .Values.global.provisioningInterface }}
{{- end }}
{{- if .Values.global.provisioningIP }}
PROVISIONING_IP: {{ .Values.global.provisioningIP }}
{{- end }}
IRONIC_INSPECTOR_VLAN_INTERFACES: all
IRONIC_ILO_USE_SWIFT: "false"
IRONIC_ILO_USE_WEB_SERVER_FOR_IMAGES: "true"
IRONIC_FAST_TRACK: "true"
IRONIC_USE_MARIADB: "true"
LISTEN_ALL_INTERFACES: "true"
{{- if .Values.global.ironicIP }}
IRONIC_IP: {{ .Values.global.ironicIP }}
{{- end }}
{{- if ( .Values.global.enable_tls ) }}
RESTART_CONTAINER_CERTIFICATE_UPDATED: "true"
IRONIC_KERNEL_PARAMS: {{ .Values.global.ironicKernelParams }} tls.enabled=true
IPA_INSECURE: "0"
IRONIC_REVERSE_PROXY_SETUP: "true"
INSPECTOR_REVERSE_PROXY_SETUP: "true"
{{- if ( .Values.global.enable_vmedia_tls ) }}
VMEDIA_TLS_PORT: "{{ .Values.global.vmediaTLSPort }}"
{{- end }}
{{- else }}
RESTART_CONTAINER_CERTIFICATE_UPDATED: "false"
IRONIC_KERNEL_PARAMS: {{ .Values.global.ironicKernelParams }}
IPA_INSECURE: "1"
IRONIC_REVERSE_PROXY_SETUP: "false"
{{- end }}
{{- if ( .Values.global.enable_basicAuth ) }}
AUTH_STRATEGY: "http_basic"
INSPECTOR_AUTH_STRATEGY: "http_basic"
{{- end }}
MARIADB_HOST: {{ .Values.global.databaseServiceName }}.{{ .Release.Namespace }}.svc.cluster.local

View File

@ -0,0 +1,367 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "ironic.fullname" . }}
labels:
{{- include "ironic.labels" . | nindent 4 }}
spec:
minReadySeconds: 10
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "ironic.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "ironic.selectorLabels" . | nindent 8 }}
spec:
{{- if .Values.podSecurityContext }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- end }}
{{- if .Values.baremetaloperator.ironichostNetwork }}
hostNetwork: {{ .Values.baremetaloperator.ironichostNetwork }}
{{- end }}
containers:
- name: ironic-httpd
image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }}
imagePullPolicy: {{ .Values.images.ironic.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
command:
- /bin/runhttpd
envFrom:
- configMapRef:
name: ironic-bmo
livenessProbe:
exec:
command:
- /bin/sh
- -c
- curl {{ if and .Values.global.enable_tls .Values.global.enable_vmedia_tls }}-sSfk https://127.0.0.1:{{ .Values.global.vmediaTLSPort }}/boot.ipxe {{ else }}-sSf http://127.0.0.1:6180/boot.ipxe{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ports:
{{- if and .Values.global.enable_tls .Values.global.enable_vmedia_tls }}
- containerPort: {{ .Values.global.vmediaTLSPort }}
name: httpd-tls
protocol: TCP
{{- else }}
- containerPort: 6180
name: httpd
protocol: TCP
{{- end }}
readinessProbe:
exec:
command:
- /bin/sh
- -c
- curl {{ if and .Values.global.enable_tls .Values.global.enable_vmedia_tls }}-sSfk https://127.0.0.1:{{ .Values.global.vmediaTLSPort }}/boot.ipxe {{ else }}-sSf http://127.0.0.1:6180/boot.ipxe{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
{{- if .Values.global.enable_tls }}
{{- include "ironic.CAVolumeMounts" . | nindent 10 }}
- name: cert-ironic
mountPath: "/certs/ironic"
readOnly: true
- name: cert-ironic-inspector
mountPath: "/certs/ironic-inspector"
readOnly: true
{{- if .Values.global.enable_vmedia_tls }}
- name: cert-ironic-vmedia
mountPath: "/certs/vmedia"
readOnly: true
{{- end }}
- mountPath: /shared/html/tstcerts
name: cert-ironic-ca
readOnly: true
{{- end }}
- name: ironic-inspector
image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }}
imagePullPolicy: {{ .Values.images.ironic.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
command:
- /bin/runironic-inspector
envFrom:
- configMapRef:
name: ironic-bmo
env:
{{- if .Values.global.enable_basicAuth }}
- name: INSPECTOR_HTPASSWD
valueFrom:
secretKeyRef:
name: ironic-inspector-basic-auth
key: htpasswd
{{- end }}
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: ironic-mariadb
livenessProbe:
exec:
command:
- /bin/sh
- -c
- curl -sSf http://127.0.0.1:{{ if .Values.global.enable_tls }}5049{{ else }}5050{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ports:
- containerPort: 5050
name: inspector
protocol: TCP
readinessProbe:
exec:
command:
- /bin/sh
- -c
- curl -sSf http://127.0.0.1:{{ if .Values.global.enable_tls }}5049{{ else }}5050{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
{{- if .Values.global.enable_basicAuth }}
- mountPath: "/auth/ironic/auth-config"
name: ironic-basic-auth
subPath: auth-config
readOnly: true
- mountPath: "/auth/ironic-inspector/auth-config"
name: ironic-inspector-basic-auth
subPath: auth-config
readOnly: true
{{- end }}
{{- if .Values.global.enable_tls }}
{{- include "ironic.CAVolumeMounts" . | nindent 10 }}
- name: cert-ironic-inspector
mountPath: "/certs/ironic-inspector"
readOnly: true
{{- end }}
- name: ironic-log-watch
image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }}
imagePullPolicy: {{ .Values.images.ironic.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
command:
- /bin/runlogwatch.sh
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
- name: ironic
image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }}
imagePullPolicy: {{ .Values.images.ironic.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
command:
- /bin/runironic
envFrom:
- configMapRef:
name: ironic-bmo
env:
{{- if .Values.global.enable_basicAuth }}
- name: IRONIC_HTPASSWD
valueFrom:
secretKeyRef:
name: ironic-basic-auth
key: htpasswd
{{- end }}
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: ironic-mariadb
livenessProbe:
exec:
command:
- /bin/sh
- -c
- curl -sSf http://127.0.0.1:{{ if .Values.global.enable_tls }}6388{{ else }}6385{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ports:
- containerPort: 6385
name: api
protocol: TCP
readinessProbe:
exec:
command:
- /bin/sh
- -c
- curl -sSf http://127.0.0.1:{{ if .Values.global.enable_tls }}6388{{ else }}6385{{ end }}
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
{{- if .Values.global.enable_basicAuth }}
- mountPath: "/auth/ironic/auth-config"
name: ironic-basic-auth
subPath: auth-config
readOnly: true
- mountPath: "/auth/ironic-inspector/auth-config"
name: ironic-inspector-basic-auth
subPath: auth-config
readOnly: true
{{- end }}
{{- if .Values.global.enable_tls }}
{{- include "ironic.CAVolumeMounts" . | nindent 10 }}
- name: cert-ironic
mountPath: "/certs/ironic"
readOnly: true
- mountPath: /etc/pki/trust/anchors
name: trusted-certs
readOnly: true
lifecycle:
postStart:
exec:
command:
- update-ca-certificates
{{- end }}
{{- if .Values.global.enable_dnsmasq }}
- name: ironic-dnsmasq
image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }}
imagePullPolicy: {{ .Values.images.ironic.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
command:
- /bin/rundnsmasq
envFrom:
- configMapRef:
name: ironic-bmo
livenessProbe:
exec:
command:
- sh
- -c
- ss -lun | grep :67 && ss -lun | grep :69
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ports:
- containerPort: 67
name: dhcp
protocol: UDP
- containerPort: 69
name: tftp
protocol: UDP
readinessProbe:
exec:
command:
- sh
- -c
- ss -lun | grep :67 && ss -lun | grep :69
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
{{- end }}
initContainers:
- name: ironic-ipa-downloader
image: {{ .Values.images.ironicIPADownloader.repository }}:{{ .Values.images.ironicIPADownloader.tag }}
imagePullPolicy: {{ .Values.images.ironicIPADownloader.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 10 }}
command:
- /usr/local/bin/get-resource.sh
envFrom:
- configMapRef:
name: ironic-ipa-downloader
volumeMounts:
{{- include "ironic.sharedVolumeMount" . | nindent 10 }}
{{- if .Values.global.enable_tls }}
- mountPath: /tmp/ironic-certificates
name: trusted-certs
{{- end }}
volumes:
- name: ironic-data-volume
persistentVolumeClaim:
claimName: ironic-shared-volume
{{- if .Values.global.enable_basicAuth }}
- name: ironic-basic-auth
secret:
secretName: ironic-basic-auth
- name: ironic-inspector-basic-auth
secret:
secretName: ironic-inspector-basic-auth
{{- if .Values.global.enable_tls }}
- name: trusted-certs
projected:
sources:
- secret:
name: ironic-cacert
{{- if .Values.global.additionalTrustedCAs }}
- secret:
name: tls-ca-additional
{{- end }}
- name: cert-ironic-ca
secret:
secretName: ironic-cacert
- name: cert-ironic
secret:
secretName: ironic-cert
- name: cert-ironic-inspector-ca
secret:
secretName: ironic-cacert
- name: cert-ironic-inspector
secret:
secretName: ironic-inspector-cert
{{- if .Values.global.enable_vmedia_tls }}
- name: cert-ironic-vmedia-ca
secret:
secretName: ironic-cacert
- name: cert-ironic-vmedia
secret:
secretName: ironic-vmedia-cert
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.global.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.global.dnsPolicy }}
dnsPolicy:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if .Values.global.enable_tls -}}
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
spec:
ca:
secretName: ironic-cacert
{{- end }}

View File

@ -0,0 +1,24 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ironic-shared-volume
{{- if .Values.persistence.ironic.keep }}
annotations:
"helm.sh/resource-policy": keep
{{- end }}
spec:
accessModes:
{{- if .Values.persistence.ironic.accessMode }}
- {{ .Values.persistence.ironic.accessMode }}
{{- else if eq (int .Values.replicaCount) 1 }}
- ReadWriteOnce
{{- else }}
- ReadWriteMany
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.ironic.size }}
{{- if .Values.persistence.ironic.storageClass }}
storageClassName: {{ .Values.persistence.ironic.storageClass }}
{{- end }}
volumeMode: Filesystem

View File

@ -0,0 +1,16 @@
{{- if and (.Values.global.enable_tls)
(ne .Values.tlscerts.crt "")
(ne .Values.tlscerts.key "")
(ne .Values.tlscerts.cacert "") -}}
apiVersion: v1
kind: Secret
metadata:
name: ironic-cacert
labels:
{{- include "ironic.labels" . | nindent 4 }}
type: Opaque
data:
tls.crt: {{ .Values.tlscerts.crt | toString | b64enc }}
tls.key: {{ .Values.tlscerts.key | toString | b64enc }}
ca.crt: {{ .Values.tlscerts.cacert | toString | b64enc }}
{{- end }}

View File

@ -0,0 +1,62 @@
{{- if .Values.global.enable_basicAuth }}
{{- $ironicUsername := "" -}}
{{- $ironicPassword := "" -}}
{{- $ironicSecretName := "ironic-basic-auth" -}}
# Check if the secret is deployed and has a password
{{- $oldIronicSecret := lookup "v1" "Secret" .Release.Namespace $ironicSecretName }}
{{- if and $oldIronicSecret (index $oldIronicSecret.data "username") (index $oldIronicSecret.data "password") }}
{{- $ironicUsername = b64dec (index $oldIronicSecret.data "username" | toString) -}}
{{- $ironicPassword = b64dec (index $oldIronicSecret.data "password" | toString) -}}
# If not, check if a username and password are provided in values.yaml
{{- else if and (.Values.global.auth.ironicUsername) (.Values.global.auth.ironicPassword) }}
{{- $ironicUsername = .Values.global.auth.ironicUsername -}}
{{- $ironicPassword = .Values.global.auth.ironicPassword -}}
{{- else }}
# If no username and password are provided in values.yaml, generate new ones
{{- $ironicUsername = "ironic" -}}
{{- $ironicPassword = (randAlphaNum 20) -}}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $ironicSecretName }}
type: Opaque
data:
username: {{ $ironicUsername | b64enc }}
password: {{ $ironicPassword | b64enc }}
htpasswd: {{ b64enc (htpasswd $ironicUsername $ironicPassword) }}
auth-config: |
{{- printf "[ironic]\nauth_type=http_basic\nusername: %s\npassword: %s" $ironicUsername $ironicPassword | b64enc | nindent 4 }}
---
{{- $ironicInspectorUsername := "" -}}
{{- $ironicInspectorPassword := "" -}}
{{- $inspectorSecretName := "ironic-inspector-basic-auth" -}}
# Check if the secret is deployed and has a password
{{- $oldInspectorSecret := lookup "v1" "Secret" .Release.Namespace $inspectorSecretName }}
{{- if and $oldInspectorSecret (index $oldInspectorSecret.data "username") (index $oldInspectorSecret.data "password") }}
{{- $ironicInspectorUsername = b64dec (index $oldInspectorSecret.data "username" | toString) -}}
{{- $ironicInspectorPassword = b64dec (index $oldInspectorSecret.data "password" | toString) -}}
# If not, check if a username and password are provided in values.yaml
{{- else if and (.Values.global.auth.ironicInspectorUsername) (.Values.global.auth.ironicInspectorPassword) }}
{{- $ironicInspectorUsername = .Values.global.auth.ironicInspectorUsername -}}
{{- $ironicInspectorPassword = .Values.global.auth.ironicInspectorPassword -}}
{{- else }}
# If no username and password are provided in values.yaml, generate new ones
{{- $ironicInspectorUsername = "ironic" -}}
{{- $ironicInspectorPassword = (randAlphaNum 20) -}}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $inspectorSecretName }}
type: Opaque
data:
username: {{ $ironicInspectorUsername | b64enc }}
password: {{ $ironicInspectorPassword | b64enc }}
htpasswd: {{ b64enc (htpasswd $ironicInspectorUsername $ironicInspectorPassword) }}
auth-config: |
{{- printf "[inspector]\nauth_type=http_basic\nusername: %s\npassword: %s" $ironicInspectorUsername $ironicInspectorPassword | b64enc | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "ironic.fullname" . }}
labels:
{{- include "ironic.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}
{{- range .Values.service.ports }}
{{- if and (eq .name "httpd") (or (not $enableTLS) (not $enableVMediaTLS)) }}
- name: {{ .name }}
port: {{ .port }}
protocol: {{ .protocol }}
targetPort: {{ .targetPort }}
{{- else if and (eq .name "httpd-tls") ($enableTLS) ($enableVMediaTLS) }}
- name: {{ .name }}
port: {{ .port }}
protocol: {{ .protocol }}
targetPort: {{ .targetPort }}
{{- else if and (ne .name "httpd") (ne .name "httpd-tls") }}
- name: {{ .name }}
port: {{ .port }}
protocol: {{ .protocol }}
targetPort: {{ .targetPort }}
{{- end }}
{{- end }}
selector:
{{- include "ironic.selectorLabels" . | nindent 4 }}
{{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }}
externalIPs:
{{- toYaml .Values.service.externalIPs | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "ironic.serviceAccountName" . }}
labels:
{{- include "ironic.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,153 @@
# Default values for ironic.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
# whether to enable dnsmasq on the provisioning network (for PXE boot)
enable_dnsmasq: false
# whether to enable PXE boot capability
# NOTE: enable_dnsmasq must set to 'true' in order for this option to be effective.
enable_pxe_boot: false
# DNS Policy of the Ironic pod
dnsPolicy: "ClusterFirstWithHostNet"
# IP address of the router associated with the specified DHCP
# address range
dnsmasqDefaultRouter: ""
# IP address of the dns server to be provided with DHCP
# response
dnsmasqDNSServer: ""
# specify comma-delimited xrange of IP addresses the DHCP server will manage.
# e.g 192.168.20.20,192.168.20.80
dhcpRange: ""
# Network interface on which provisioning network can be accessed
# Note this must be a dedicated NIC separate from the controlplane network
provisioningInterface: ""
# IP Address assigned to network interface on provisioning network
provisioningIP: ""
# Whether the NIC names should be predictable or not
predictableNicNames: "true"
# The kernel params for Ironic
ironicKernelParams: "console=ttyS0"
databaseServiceName: "metal3-mariadb"
# In a multi-node kubernetes cluster, we need to "pin" the
# ironic containers to the given host where the
# provisioningIP exists. Uncomment the nodeSelector
# here and update the hostname accordingly.
#nodeSelector:
#kubernetes.io/hostname: "csrancher-n1"
# Comment this out when pinning the pdns containers to a specfic host.
nodeSelector: {}
replicaCount: 1
images:
ironic:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic
pullPolicy: IfNotPresent
tag: 24.1.2.0
ironicIPADownloader:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic-ipa-downloader
pullPolicy: IfNotPresent
tag: 2.0.0
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
runAsUser: 10475
fsGroup: 10475
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
runAsNonRoot: true
service:
type: LoadBalancer
annotations: {}
externalIPs: []
ports:
- name: httpd
port: 6180
protocol: TCP
targetPort: 6180
- name: httpd-tls
port: 6185
protocol: TCP
targetPort: 6185
- name: inspector
port: 5050
protocol: TCP
targetPort: 5050
- name: api
port: 6385
protocol: TCP
targetPort: 6385
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
tolerations: []
affinity: {}
baremetaloperator:
cloudflareApiToken: "foo"
ironichostNetwork: true
debug:
ironicRamdiskSshKey: ""
tlscerts:
cacert: ""
key: ""
crt: ""
persistence:
ironic:
# storageClass for the ironic shared volume
# Ensure the storageClass is defined
storageClass: ""
# size of the ironic shared volume
size: "1Gi"
# accessMode of the ironic shared volume PVC
# If empty defaults to ReadWriteOnce when replicaCount=1 otherwise ReadWriteMany
accessMode: ""
# flag to indicate to keep pvc upon helm uninstall
keep: false

View File

@ -0,0 +1,24 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 10.6.7
description: A Helm chart for MariaDB, used by Metal3
name: mariadb
type: application
version: 0.5.4

View File

@ -0,0 +1,64 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "mariadb.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "mariadb.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "mariadb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "mariadb.labels" -}}
helm.sh/chart: {{ include "mariadb.chart" . }}
{{ include "mariadb.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "mariadb.selectorLabels" -}}
app.kubernetes.io/component: mariadb
app.kubernetes.io/name: {{ include "mariadb.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "mariadb.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "mariadb.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-cm
labels:
{{- include "mariadb.labels" . | nindent 4 }}
data:
RESTART_CONTAINER_CERTIFICATE_UPDATED: "false"

View File

@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mariadb.fullname" . }}
labels:
{{- include "mariadb.labels" . | nindent 4 }}
spec:
replicas: {{.Values.replicaCount}}
selector:
matchLabels:
{{- include "mariadb.selectorLabels" . | nindent 6 }}
strategy:
type: Recreate
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "mariadb.selectorLabels" . | nindent 8 }}
spec:
{{- $volmounts := toYaml .Values.volumeMounts | trim | nindent 12 }}
{{- $volumes := toYaml .Values.volumes | trim | nindent 8 }}
serviceAccountName: {{ include "mariadb.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: mariadb
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
env:
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: ironic-mariadb
- name: RESTART_CONTAINER_CERTIFICATE_UPDATED
valueFrom:
configMapKeyRef:
name: mariadb-cm
key: RESTART_CONTAINER_CERTIFICATE_UPDATED
lifecycle:
preStop:
exec:
command:
- sh
- -c
- mysqladmin shutdown -uironic -p$(printenv MARIADB_PASSWORD)
livenessProbe:
exec:
command:
- sh
- -c
- mysqladmin status -uironic -p$(printenv MARIADB_PASSWORD)
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
ports:
- containerPort: 3306
name: mariadb
protocol: TCP
readinessProbe:
exec:
command:
- sh
- -c
- mysqladmin status -uironic -p$(printenv MARIADB_PASSWORD)
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
volumeMounts:
{{- $volmounts }}
{{- with .Values.global.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
{{- $volumes }}

View File

@ -0,0 +1,24 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-volume-claim
{{- if .Values.persistence.keep }}
annotations:
"helm.sh/resource-policy": keep
{{- end }}
spec:
accessModes:
{{- if .Values.persistence.accessMode }}
- {{ .Values.persistence.accessMode }}
{{- else if eq (int .Values.replicaCount) 1 }}
- ReadWriteOnce
{{- else }}
- ReadWriteMany
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- if .Values.persistence.storageClass }}
storageClassName: {{ .Values.persistence.storageClass }}
{{- end }}
volumeMode: Filesystem

View File

@ -0,0 +1,21 @@
{{- $secret_name := "ironic-mariadb" -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ $secret_name }}
labels:
{{- include "mariadb.labels" . | nindent 4 }}
type: Opaque
data:
# Check if the secret is deployed and has a password
{{- $old_sec := lookup "v1" "Secret" .Release.Namespace $secret_name }}
{{- if and $old_sec (index $old_sec.data "password") }}
password: {{ index $old_sec.data "password" }}
{{- else if .Values.password }}
# If not, check if a password is provided in values.yaml
password: {{ .Values.password | toString | b64enc }}
{{- else }}
# If no secret and no password in values.yaml, generate a new password
password: {{ randAlphaNum 20 | b64enc }}
{{- end }}

View File

@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "mariadb.serviceAccountName" . }}
labels:
{{- include "mariadb.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.global.databaseServiceName }}
labels:
{{- include "mariadb.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
selector:
{{- include "mariadb.selectorLabels" . | nindent 4 }}
ports:
{{- with .Values.service.ports }}
{{- toYaml . | nindent 2 }}
{{- end }}

View File

@ -0,0 +1,67 @@
global:
databaseServiceName: "metal3-mariadb"
nodeSelector: {}
replicaCount: 1
service:
type: ClusterIP
ports:
- protocol: TCP
port: 3306
targetPort: 3306
image:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/suse/mariadb
pullPolicy: IfNotPresent
tag: 10.6.15.1
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
runAsUser: 10060
fsGroup: 10060
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
runAsNonRoot: true
# Password for the mariadb ironic user
password: ""
persistence:
# storageClass for the mariadb data volume
storageClass: ""
# size of the mariadb data volume
size: "1Gi"
# accessMode of the mariadb data volume PVC
# If empty defaults to ReadWriteOnce when replicaCount=1 otherwise ReadWriteMany
accessMode: ""
# flag to indicate to keep pvc upon helm uninstall
keep: false
volumeMounts:
- name: mariadb-data-volume
mountPath: /var/lib/mysql
volumes:
- name: mariadb-data-volume
persistentVolumeClaim:
claimName: mariadb-volume-claim

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Media, used by Metal3
name: media
type: application
version: 0.5.0

View File

@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "media.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "media.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "media.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "media.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -0,0 +1,63 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "media.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "media.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "media.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "media.labels" -}}
helm.sh/chart: {{ include "media.chart" . }}
{{ include "media.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "media.selectorLabels" -}}
app.kubernetes.io/component: media
app.kubernetes.io/name: {{ include "media.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "media.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "media.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "media.fullname" . }}
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "media.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
rollme: {{ randAlphaNum 5 | quote }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "media.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "media.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- with .Values.volumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
command:
- /usr/sbin/httpd
args:
- -DFOREGROUND
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
{{- with .Values.volumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.global.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "media.fullname" . }}
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "media.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "media.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "media.labels" . | nindent 4 }}
{{- with $_ := merge .Values.ingress.annotations $.Values.global.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ tpl .host $ }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,18 @@
{{- if eq .Values.mediaVolume.storageClassName "local" }}
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: media
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
storageClassName: {{ .Values.mediaVolume.storageClassName }}
accessModes:
{{ toYaml .Values.mediaVolume.accessModes }}
capacity:
storage: {{ .Values.mediaVolume.storage }}
hostPath:
path: {{ .Values.mediaVolume.hostPath }}
type: DirectoryOrCreate
{{- end }}

View File

@ -0,0 +1,14 @@
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: media
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
storageClassName: {{ .Values.mediaVolume.storageClassName }}
accessModes:
{{ toYaml .Values.mediaVolume.accessModes }}
resources:
requests:
storage: {{ .Values.mediaVolume.storage }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "media.fullname" . }}
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "media.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "media.serviceAccountName" . }}
labels:
{{- include "media.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,9 @@
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: {{ include "media.fullname" . }}
labels:
{{- include "media.labels" . | nindent 4 }}
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "media.fullname" . }}-test-connection"
labels:
{{- include "media.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "media.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@ -0,0 +1,117 @@
# Default values for media.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
global:
# Global ingress annotations that is shared by all the ingress services.
# For example, use it to override extern-dns records.
ingress:
annotations: {}
# The IP to register with external-dns for this service
#external-dns.alpha.kubernetes.io/target: 192.168.20.5
# If running in a multi-node kubernetes cluster, "pin" the media container
# to the given host where the /opt/media volume exists. Uncomment the
# nodeSelector and update the hostname accordingly.
#nodeSelector:
#kubernetes.io/hostname: "my-hostname"
# Comment this out when pinning the media container to a specfic host.
nodeSelector: {}
replicaCount: 1
image:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic
pullPolicy: IfNotPresent
tag: 24.1.2.0
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
runAsUser: 10475
fsGroup: 10475
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
runAsNonRoot: true
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: media.suse.baremetal
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
tolerations: []
affinity: {}
# volumes
volumes:
- name: assets
persistentVolumeClaim:
claimName: media
# volume mounts
volumeMounts:
- mountPath: /srv/www/htdocs
name: assets
# media volume settings
mediaVolume:
storageClassName: local
accessModes:
- ReadOnlyMany
hostPath: /opt/media
storage: 5Gi

View File

@ -0,0 +1,3 @@
TBD: Document the deployed application/service endpoints
You should now be ready to install and configure ClusterAPI.

Binary file not shown.

View File

@ -0,0 +1,11 @@
apiVersion: v2
appVersion: v0.0.14
description: A cloud native wrapper of FRR
home: https://metallb.universe.tf
icon: https://metallb.universe.tf/images/logo/metallb-white.png
kubeVersion: '>= 1.19.0-0'
name: frr-k8s
sources:
- https://github.com/metallb/frr-k8s
type: application
version: 0.0.15

View File

@ -0,0 +1,96 @@
# frr-k8s
![Version: 0.0.14](https://img.shields.io/badge/Version-0.0.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.0.14](https://img.shields.io/badge/AppVersion-v0.0.14-informational?style=flat-square)
A cloud native wrapper of FRR
**Homepage:** <https://metallb.universe.tf>
## Source Code
* <https://github.com/metallb/frr-k8s>
## Requirements
Kubernetes: `>= 1.19.0-0`
| Repository | Name | Version |
|------------|------|---------|
| | crds | 0.0.14 |
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| crds.enabled | bool | `true` | |
| crds.validationFailurePolicy | string | `"Fail"` | |
| frrk8s.affinity | object | `{}` | |
| frrk8s.alwaysBlock | string | `""` | |
| frrk8s.disableCertRotation | bool | `false` | |
| frrk8s.frr.image.pullPolicy | string | `nil` | |
| frrk8s.frr.image.repository | string | `"quay.io/frrouting/frr"` | |
| frrk8s.frr.image.tag | string | `"9.1.0"` | |
| frrk8s.frr.metricsBindAddress | string | `"127.0.0.1"` | |
| frrk8s.frr.metricsPort | int | `7573` | |
| frrk8s.frr.resources | object | `{}` | |
| frrk8s.frr.secureMetricsPort | int | `9141` | |
| frrk8s.frrMetrics.resources | object | `{}` | |
| frrk8s.healthPort | int | `8081` | |
| frrk8s.image.pullPolicy | string | `nil` | |
| frrk8s.image.repository | string | `"quay.io/metallb/frr-k8s"` | |
| frrk8s.image.tag | string | `nil` | |
| frrk8s.labels.app | string | `"frr-k8s"` | |
| frrk8s.livenessProbe.enabled | bool | `true` | |
| frrk8s.livenessProbe.failureThreshold | int | `3` | |
| frrk8s.livenessProbe.initialDelaySeconds | int | `10` | |
| frrk8s.livenessProbe.periodSeconds | int | `10` | |
| frrk8s.livenessProbe.successThreshold | int | `1` | |
| frrk8s.livenessProbe.timeoutSeconds | int | `1` | |
| frrk8s.logLevel | string | `"info"` | Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none` |
| frrk8s.nodeSelector | object | `{}` | |
| frrk8s.podAnnotations | object | `{}` | |
| frrk8s.priorityClassName | string | `""` | |
| frrk8s.readinessProbe.enabled | bool | `true` | |
| frrk8s.readinessProbe.failureThreshold | int | `3` | |
| frrk8s.readinessProbe.initialDelaySeconds | int | `10` | |
| frrk8s.readinessProbe.periodSeconds | int | `10` | |
| frrk8s.readinessProbe.successThreshold | int | `1` | |
| frrk8s.readinessProbe.timeoutSeconds | int | `1` | |
| frrk8s.reloader.resources | object | `{}` | |
| frrk8s.resources | object | `{}` | |
| frrk8s.restartOnRotatorSecretRefresh | bool | `false` | |
| frrk8s.runtimeClassName | string | `""` | |
| frrk8s.serviceAccount.annotations | object | `{}` | |
| frrk8s.serviceAccount.create | bool | `true` | |
| frrk8s.serviceAccount.name | string | `""` | |
| frrk8s.startupProbe.enabled | bool | `true` | |
| frrk8s.startupProbe.failureThreshold | int | `30` | |
| frrk8s.startupProbe.periodSeconds | int | `5` | |
| frrk8s.tolerateMaster | bool | `true` | |
| frrk8s.tolerations | list | `[]` | |
| frrk8s.updateStrategy.type | string | `"RollingUpdate"` | |
| fullnameOverride | string | `""` | |
| nameOverride | string | `""` | |
| prometheus.metricsBindAddress | string | `"127.0.0.1"` | |
| prometheus.metricsPort | int | `7572` | |
| prometheus.metricsTLSSecret | string | `""` | |
| prometheus.namespace | string | `""` | |
| prometheus.rbacPrometheus | bool | `false` | |
| prometheus.rbacProxy.pullPolicy | string | `nil` | |
| prometheus.rbacProxy.repository | string | `"gcr.io/kubebuilder/kube-rbac-proxy"` | |
| prometheus.rbacProxy.tag | string | `"v0.12.0"` | |
| prometheus.scrapeAnnotations | bool | `false` | |
| prometheus.secureMetricsPort | int | `9140` | |
| prometheus.serviceAccount | string | `""` | |
| prometheus.serviceMonitor.additionalLabels | object | `{}` | |
| prometheus.serviceMonitor.annotations | object | `{}` | |
| prometheus.serviceMonitor.enabled | bool | `false` | |
| prometheus.serviceMonitor.interval | string | `nil` | |
| prometheus.serviceMonitor.jobLabel | string | `"app.kubernetes.io/name"` | |
| prometheus.serviceMonitor.metricRelabelings | list | `[]` | |
| prometheus.serviceMonitor.relabelings | list | `[]` | |
| prometheus.serviceMonitor.tlsConfig.insecureSkipVerify | bool | `true` | |
| rbac.create | bool | `true` | |
----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0)

View File

@ -0,0 +1,462 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
name: frrconfigurations.frrk8s.metallb.io
spec:
group: frrk8s.metallb.io
names:
kind: FRRConfiguration
listKind: FRRConfigurationList
plural: frrconfigurations
singular: frrconfiguration
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: FRRConfiguration is a piece of FRR configuration.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FRRConfigurationSpec defines the desired state of FRRConfiguration.
properties:
bgp:
description: BGP is the configuration related to the BGP protocol.
properties:
bfdProfiles:
description: BFDProfiles is the list of bfd profiles to be used
when configuring the neighbors.
items:
description: |-
BFDProfile is the configuration related to the BFD protocol associated
to a BGP session.
properties:
detectMultiplier:
description: |-
Configures the detection multiplier to determine
packet loss. The remote transmission interval will be multiplied
by this value to determine the connection loss detection timer.
format: int32
maximum: 255
minimum: 2
type: integer
echoInterval:
description: |-
Configures the minimal echo receive transmission
interval that this system is capable of handling in milliseconds.
Defaults to 50ms
format: int32
maximum: 60000
minimum: 10
type: integer
echoMode:
description: |-
Enables or disables the echo transmission mode.
This mode is disabled by default, and not supported on multi
hops setups.
type: boolean
minimumTtl:
description: |-
For multi hop sessions only: configure the minimum
expected TTL for an incoming BFD control packet.
format: int32
maximum: 254
minimum: 1
type: integer
name:
description: |-
The name of the BFD Profile to be referenced in other parts
of the configuration.
type: string
passiveMode:
description: |-
Mark session as passive: a passive session will not
attempt to start the connection and will wait for control packets
from peer before it begins replying.
type: boolean
receiveInterval:
description: |-
The minimum interval that this system is capable of
receiving control packets in milliseconds.
Defaults to 300ms.
format: int32
maximum: 60000
minimum: 10
type: integer
transmitInterval:
description: |-
The minimum transmission interval (less jitter)
that this system wants to use to send BFD control packets in
milliseconds. Defaults to 300ms
format: int32
maximum: 60000
minimum: 10
type: integer
required:
- name
type: object
type: array
routers:
description: Routers is the list of routers we want FRR to configure
(one per VRF).
items:
description: Router represent a neighbor router we want FRR
to connect to.
properties:
asn:
description: ASN is the AS number to use for the local end
of the session.
format: int32
maximum: 4294967295
minimum: 0
type: integer
id:
description: ID is the BGP router ID
type: string
imports:
description: Imports is the list of imported VRFs we want
for this router / vrf.
items:
description: Import represents the possible imported VRFs
to a given router.
properties:
vrf:
description: Vrf is the vrf we want to import from
type: string
type: object
type: array
neighbors:
description: Neighbors is the list of neighbors we want
to establish BGP sessions with.
items:
description: Neighbor represents a BGP Neighbor we want
FRR to connect to.
properties:
address:
description: Address is the IP address to establish
the session with.
type: string
asn:
description: ASN is the AS number to use for the local
end of the session.
format: int32
maximum: 4294967295
minimum: 0
type: integer
bfdProfile:
description: |-
BFDProfile is the name of the BFD Profile to be used for the BFD session associated
to the BGP session. If not set, the BFD session won't be set up.
type: string
connectTime:
description: Requested BGP connect time, controls
how long BGP waits between connection attempts to
a neighbor.
type: string
x-kubernetes-validations:
- message: connect time should be between 1 seconds
to 65535
rule: duration(self).getSeconds() >= 1 && duration(self).getSeconds()
<= 65535
- message: connect time should contain a whole number
of seconds
rule: duration(self).getMilliseconds() % 1000 ==
0
disableMP:
default: false
description: To set if we want to disable MP BGP that
will separate IPv4 and IPv6 route exchanges into
distinct BGP sessions.
type: boolean
ebgpMultiHop:
description: EBGPMultiHop indicates if the BGPPeer
is multi-hops away.
type: boolean
enableGracefulRestart:
description: |-
EnableGracefulRestart allows BGP peer to continue to forward data packets along
known routes while the routing protocol information is being restored. If
the session is already established, the configuration will have effect
after reconnecting to the peer
type: boolean
holdTime:
description: |-
HoldTime is the requested BGP hold time, per RFC4271.
Defaults to 180s.
type: string
keepaliveTime:
description: |-
KeepaliveTime is the requested BGP keepalive time, per RFC4271.
Defaults to 60s.
type: string
password:
description: |-
Password to be used for establishing the BGP session.
Password and PasswordSecret are mutually exclusive.
type: string
passwordSecret:
description: |-
PasswordSecret is name of the authentication secret for the neighbor.
the secret must be of type "kubernetes.io/basic-auth", and created in the
same namespace as the frr-k8s daemon. The password is stored in the
secret as the key "password".
Password and PasswordSecret are mutually exclusive.
properties:
name:
description: name is unique within a namespace
to reference a secret resource.
type: string
namespace:
description: namespace defines the space within
which the secret name must be unique.
type: string
type: object
x-kubernetes-map-type: atomic
port:
description: |-
Port is the port to dial when establishing the session.
Defaults to 179.
maximum: 16384
minimum: 0
type: integer
sourceaddress:
description: |-
SourceAddress is the IPv4 or IPv6 source address to use for the BGP
session to this neighbour, may be specified as either an IP address
directly or as an interface name
type: string
toAdvertise:
description: |-
ToAdvertise represents the list of prefixes to advertise to the given neighbor
and the associated properties.
properties:
allowed:
description: |-
Allowed is is the list of prefixes allowed to be propagated to
this neighbor. They must match the prefixes defined in the router.
properties:
mode:
default: filtered
description: |-
Mode is the mode to use when handling the prefixes.
When set to "filtered", only the prefixes in the given list will be allowed.
When set to "all", all the prefixes configured on the router will be allowed.
enum:
- all
- filtered
type: string
prefixes:
items:
type: string
type: array
type: object
withCommunity:
description: |-
PrefixesWithCommunity is a list of prefixes that are associated to a
bgp community when being advertised. The prefixes associated to a given local pref
must be in the prefixes allowed to be advertised.
items:
description: CommunityPrefixes is a list of
prefixes associated to a community.
properties:
community:
description: Community is the community
associated to the prefixes.
type: string
prefixes:
description: Prefixes is the list of prefixes
associated to the community.
format: cidr
items:
type: string
minItems: 1
type: array
type: object
type: array
withLocalPref:
description: |-
PrefixesWithLocalPref is a list of prefixes that are associated to a local
preference when being advertised. The prefixes associated to a given local pref
must be in the prefixes allowed to be advertised.
items:
description: LocalPrefPrefixes is a list of
prefixes associated to a local preference.
properties:
localPref:
description: LocalPref is the local preference
associated to the prefixes.
format: int32
type: integer
prefixes:
description: Prefixes is the list of prefixes
associated to the local preference.
format: cidr
items:
type: string
minItems: 1
type: array
type: object
type: array
type: object
toReceive:
description: ToReceive represents the list of prefixes
to receive from the given neighbor.
properties:
allowed:
description: |-
Allowed is the list of prefixes allowed to be received from
this neighbor.
properties:
mode:
default: filtered
description: |-
Mode is the mode to use when handling the prefixes.
When set to "filtered", only the prefixes in the given list will be allowed.
When set to "all", all the prefixes configured on the router will be allowed.
enum:
- all
- filtered
type: string
prefixes:
items:
description: PrefixSelector is a filter
of prefixes to receive.
properties:
ge:
description: |-
The prefix length modifier. This selector accepts any matching prefix with length
greater or equal the given value.
format: int32
maximum: 128
minimum: 1
type: integer
le:
description: |-
The prefix length modifier. This selector accepts any matching prefix with length
less or equal the given value.
format: int32
maximum: 128
minimum: 1
type: integer
prefix:
format: cidr
type: string
type: object
type: array
type: object
type: object
required:
- address
- asn
type: object
type: array
prefixes:
description: Prefixes is the list of prefixes we want to
advertise from this router instance.
items:
type: string
type: array
vrf:
description: VRF is the host vrf used to establish sessions
from this router.
type: string
required:
- asn
type: object
type: array
type: object
nodeSelector:
description: |-
NodeSelector limits the nodes that will attempt to apply this config.
When specified, the configuration will be considered only on nodes
whose labels match the specified selectors.
When it is not specified all nodes will attempt to apply this config.
properties:
matchExpressions:
description: matchExpressions is a list of label selector requirements.
The requirements are ANDed.
items:
description: |-
A label selector requirement is a selector that contains values, a key, and an operator that
relates the key and values.
properties:
key:
description: key is the label key that the selector applies
to.
type: string
operator:
description: |-
operator represents a key's relationship to a set of values.
Valid operators are In, NotIn, Exists and DoesNotExist.
type: string
values:
description: |-
values is an array of string values. If the operator is In or NotIn,
the values array must be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced during a strategic
merge patch.
items:
type: string
type: array
x-kubernetes-list-type: atomic
required:
- key
- operator
type: object
type: array
x-kubernetes-list-type: atomic
matchLabels:
additionalProperties:
type: string
description: |-
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
raw:
description: |-
Raw is a snippet of raw frr configuration that gets appended to the
one rendered translating the type safe API.
properties:
priority:
description: |-
Priority is the order with this configuration is appended to the
bottom of the rendered configuration. A higher value means the
raw config is appended later in the configuration file.
type: integer
rawConfig:
description: |-
Config is a raw FRR configuration to be appended to the configuration
rendered via the k8s api.
type: string
type: object
type: object
status:
description: FRRConfigurationStatus defines the observed state of FRRConfiguration.
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,65 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
name: frrnodestates.frrk8s.metallb.io
spec:
group: frrk8s.metallb.io
names:
kind: FRRNodeState
listKind: FRRNodeStateList
plural: frrnodestates
singular: frrnodestate
scope: Cluster
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: FRRNodeState exposes the status of the FRR instance running on
each node.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FRRNodeStateSpec defines the desired state of FRRNodeState.
type: object
status:
description: FRRNodeStateStatus defines the observed state of FRRNodeState.
properties:
lastConversionResult:
description: LastConversionResult is the status of the last translation
between the `FRRConfiguration`s resources and FRR's configuration,
contains "success" or an error.
type: string
lastReloadResult:
description: LastReloadResult represents the status of the last configuration
update operation by FRR, contains "success" or an error.
type: string
runningConfig:
description: RunningConfig represents the current FRR running config,
which is the configuration the FRR instance is currently running
with.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,4 @@
FRR-k8s is now running in the cluster.
Now you can configure it via its CRs. Please refer to the frr-k8s official docs
on how to use the CRs.

View File

@ -0,0 +1,63 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "frrk8s.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "frrk8s.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "frrk8s.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "frrk8s.labels" -}}
helm.sh/chart: {{ include "frrk8s.chart" . }}
{{ include "frrk8s.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "frrk8s.selectorLabels" -}}
app.kubernetes.io/name: {{ include "frrk8s.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the frrk8s service account to use
*/}}
{{- define "frrk8s.serviceAccountName" -}}
{{- if .Values.frrk8s.serviceAccount.create }}
{{- default (printf "%s-controller" (include "frrk8s.fullname" .)) .Values.frrk8s.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.frrk8s.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,431 @@
# FRR expects to have these files owned by frr:frr on startup.
# Having them in a ConfigMap allows us to modify behaviors: for example enabling more daemons on startup.
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "frrk8s.fullname" . }}-frr-startup
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "frrk8s.labels" . | nindent 4 }}
app.kubernetes.io/component: frr-k8s
data:
daemons: |
# This file tells the frr package which daemons to start.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/frr/examples/.
#
# ATTENTION:
#
# When activating a daemon for the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "frr", else
# the daemon will not be started by /etc/init.d/frr. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
# The watchfrr and zebra daemons are always started.
#
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=yes
fabricd=no
vrrpd=no
#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1"
ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options=" -A 127.0.0.1"
staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
fabricd_options="-A 127.0.0.1"
vrrpd_options=" -A 127.0.0.1"
# configuration profile
#
#frr_profile="traditional"
#frr_profile="datacenter"
#
# This is the maximum number of FD's that will be available.
# Upon startup this is read by the control files and ulimit
# is called. Uncomment and use a reasonable value for your
# setup if you are expecting a large number of peers in
# say BGP.
#MAX_FDS=1024
# The list of daemons to watch is automatically generated by the init script.
#watchfrr_options=""
# for debugging purposes, you can specify a "wrap" command to start instead
# of starting the daemon directly, e.g. to use valgrind on ospfd:
# ospfd_wrap="/usr/bin/valgrind"
# or you can use "all_wrap" for all daemons, e.g. to use perf record:
# all_wrap="/usr/bin/perf record --call-graph -"
# the normal daemon command is added to this at the end.
vtysh.conf: |+
service integrated-vtysh-config
frr.conf: |+
! This file gets overriden the first time the speaker renders a config.
! So anything configured here is only temporary.
frr version 8.0
frr defaults traditional
hostname Router
line vty
log file /etc/frr/frr.log informational
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ template "frrk8s.fullname" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "frrk8s.labels" . | nindent 4 }}
app.kubernetes.io/component: frr-k8s
{{- range $key, $value := .Values.frrk8s.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.frrk8s.updateStrategy }}
updateStrategy: {{- toYaml .Values.frrk8s.updateStrategy | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "frrk8s.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: frr-k8s
template:
metadata:
labels:
{{- include "frrk8s.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: frr-k8s
{{- range $key, $value := .Values.frrk8s.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.frrk8s.runtimeClassName }}
runtimeClassName: {{ .Values.frrk8s.runtimeClassName }}
{{- end }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "frrk8s.serviceAccountName" . }}
terminationGracePeriodSeconds: 0
hostNetwork: true
volumes:
- name: frr-sockets
emptyDir: {}
- name: frr-startup
configMap:
name: {{ template "frrk8s.fullname" . }}-frr-startup
- name: frr-conf
emptyDir: {}
- name: reloader
emptyDir: {}
- name: metrics
emptyDir: {}
{{- if .Values.prometheus.metricsTLSSecret }}
- name: metrics-certs
secret:
secretName: {{ .Values.prometheus.metricsTLSSecret }}
{{- end }}
initContainers:
# Copies the initial config files with the right permissions to the shared volume.
- name: cp-frr-files
image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }}
securityContext:
runAsUser: 100
runAsGroup: 101
command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"]
volumeMounts:
- name: frr-startup
mountPath: /tmp/frr
- name: frr-conf
mountPath: /etc/frr
# Copies the reloader to the shared volume between the speaker and reloader.
- name: cp-reloader
image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }}
command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"]
volumeMounts:
- name: reloader
mountPath: /etc/frr_reloader
# Copies the metrics exporter
- name: cp-metrics
image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }}
command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"]
volumeMounts:
- name: metrics
mountPath: /etc/frr_metrics
shareProcessNamespace: true
containers:
- name: controller
image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }}
{{- if .Values.frrk8s.image.pullPolicy }}
imagePullPolicy: {{ .Values.frrk8s.image.pullPolicy }}
{{- end }}
command:
- /frr-k8s
args:
- "--node-name=$(NODE_NAME)"
- "--namespace=$(NAMESPACE)"
- "--metrics-bind-address={{.Values.prometheus.metricsBindAddress}}:{{ .Values.prometheus.metricsPort }}"
{{- with .Values.frrk8s.logLevel }}
- --log-level={{ . }}
{{- end }}
- --health-probe-bind-address={{.Values.prometheus.metricsBindAddress}}:{{ .Values.frrk8s.healthPort }}
{{- if .Values.frrk8s.alwaysBlock }}
- --always-block={{ .Values.frrk8s.alwaysBlock }}
{{- end }}
env:
- name: FRR_CONFIG_FILE
value: /etc/frr_reloader/frr.conf
- name: FRR_RELOADER_PID_FILE
value: /etc/frr_reloader/reloader.pid
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- containerPort: {{ .Values.prometheus.metricsPort }}
name: monitoring
{{- if .Values.frrk8s.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.frrk8s.healthPort }}
host: {{ .Values.prometheus.metricsBindAddress }}
initialDelaySeconds: {{ .Values.frrk8s.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.frrk8s.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.frrk8s.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.frrk8s.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /healthz
port: {{ .Values.frrk8s.healthPort }}
host: {{ .Values.prometheus.metricsBindAddress }}
initialDelaySeconds: {{ .Values.frrk8s.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.frrk8s.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.frrk8s.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.frrk8s.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.frrk8s.readinessProbe.failureThreshold }}
{{- end }}
{{- with .Values.frrk8s.resources }}
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_RAW
volumeMounts:
- name: reloader
mountPath: /etc/frr_reloader
- name: frr
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
- NET_BIND_SERVICE
image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }}
{{- if .Values.frrk8s.frr.image.pullPolicy }}
imagePullPolicy: {{ .Values.frrk8s.frr.image.pullPolicy }}
{{- end }}
env:
- name: TINI_SUBREAPER
value: "true"
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
# The command is FRR's default entrypoint & waiting for the log file to appear and tailing it.
# If the log file isn't created in 60 seconds the tail fails and the container is restarted.
# This workaround is needed to have the frr logs as part of kubectl logs -c frr < controller_pod_name >.
command:
- /bin/sh
- -c
- |
/sbin/tini -- /usr/lib/frr/docker-start &
attempts=0
until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do
sleep 1
attempts=$(( $attempts + 1 ))
done
tail -f /etc/frr/frr.log
{{- with .Values.frrk8s.frr.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if .Values.frrk8s.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /livez
port: {{ .Values.frrk8s.frr.metricsPort }}
host: {{ .Values.frrk8s.frr.metricsBindAddress }}
periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }}
failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.frrk8s.startupProbe.enabled }}
startupProbe:
httpGet:
path: /livez
port: {{ .Values.frrk8s.frr.metricsPort }}
host: {{ .Values.frrk8s.frr.metricsBindAddress }}
failureThreshold: {{ .Values.frrk8s.startupProbe.failureThreshold }}
periodSeconds: {{ .Values.frrk8s.startupProbe.periodSeconds }}
{{- end }}
- name: reloader
image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }}
{{- if .Values.frrk8s.frr.image.pullPolicy }}
imagePullPolicy: {{ .Values.frrk8s.frr.image.pullPolicy }}
{{- end }}
command: ["/etc/frr_reloader/frr-reloader.sh"]
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
- name: reloader
mountPath: /etc/frr_reloader
{{- with .Values.frrk8s.reloader.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
- name: frr-metrics
image: {{ .Values.frrk8s.frr.image.repository }}:{{ .Values.frrk8s.frr.image.tag | default .Chart.AppVersion }}
command: ["/etc/frr_metrics/frr-metrics"]
args:
- --metrics-port={{ .Values.frrk8s.frr.metricsPort }}
- --metrics-bind-address={{ .Values.frrk8s.frr.metricsBindAddress }}
ports:
- containerPort: {{ .Values.frrk8s.frr.metricsPort }}
name: monitoring
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
- name: metrics
mountPath: /etc/frr_metrics
{{- with .Values.frrk8s.frrMetrics.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
- name: kube-rbac-proxy
image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag }}
imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }}
args:
- --logtostderr
- --secure-listen-address=:{{ .Values.prometheus.secureMetricsPort }}
- --upstream=http://{{.Values.prometheus.metricsBindAddress}}:{{ .Values.prometheus.metricsPort }}/
- --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
{{- if .Values.prometheus.metricsTLSSecret }}
- --tls-private-key-file=/etc/metrics/tls.key
- --tls-cert-file=/etc/metrics/tls.crt
{{- end }}
ports:
- containerPort: {{ .Values.prometheus.secureMetricsPort }}
name: metricshttps
resources:
requests:
cpu: 10m
memory: 20Mi
terminationMessagePolicy: FallbackToLogsOnError
{{- if .Values.prometheus.metricsTLSSecret }}
volumeMounts:
- name: metrics-certs
mountPath: /etc/metrics
readOnly: true
{{- end }}
- name: kube-rbac-proxy-frr
image: {{ .Values.prometheus.rbacProxy.repository }}:{{ .Values.prometheus.rbacProxy.tag | default .Chart.AppVersion }}
imagePullPolicy: {{ .Values.prometheus.rbacProxy.pullPolicy }}
args:
- --logtostderr
- --secure-listen-address=:{{ .Values.frrk8s.frr.secureMetricsPort }}
- --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- --upstream=http://{{ .Values.frrk8s.frr.metricsBindAddress }}:{{ .Values.frrk8s.frr.metricsPort }}/
{{- if .Values.prometheus.metricsTLSSecret }}
- --tls-private-key-file=/etc/metrics/tls.key
- --tls-cert-file=/etc/metrics/tls.crt
{{- end }}
ports:
- containerPort: {{ .Values.frrk8s.frr.secureMetricsPort }}
name: metricshttps
resources:
requests:
cpu: 10m
memory: 20Mi
terminationMessagePolicy: FallbackToLogsOnError
{{- if .Values.prometheus.metricsTLSSecret }}
volumeMounts:
- name: metrics-certs
mountPath: /etc/metrics
readOnly: true
{{- end }}
nodeSelector:
"kubernetes.io/os": linux
{{- with .Values.frrk8s.nodeSelector }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.frrk8s.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if or .Values.frrk8s.tolerateMaster .Values.frrk8s.tolerations }}
tolerations:
{{- if .Values.frrk8s.tolerateMaster }}
- key: node-role.kubernetes.io/master
effect: NoSchedule
operator: Exists
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
operator: Exists
{{- end }}
{{- with .Values.frrk8s.tolerations }}
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
{{- with .Values.frrk8s.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}

View File

@ -0,0 +1,73 @@
{{- if .Values.rbac.create -}}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "frrk8s.fullname" . }}-controller
labels: {{- include "frrk8s.labels" . | nindent 4 }}
rules:
- apiGroups: ["frrk8s.metallb.io"]
resources: ["frrconfigurations"]
verbs: ["get", "list", "watch"]
- apiGroups: ["frrk8s.metallb.io"]
resources: ["frrnodestates"]
verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
- apiGroups: ["frrk8s.metallb.io"]
resources: ["frrnodestates/status"]
verbs: ["get", "patch", "update"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: ["create"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingwebhookconfigurations"]
verbs: ["get", "list", "watch"]
- apiGroups: ["admissionregistration.k8s.io"]
resourceNames: ["frr-k8s-validating-webhook-configuration"]
resources: ["validatingwebhookconfigurations"]
verbs: ["update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "frrk8s.fullname" . }}-controller
labels: {{- include "frrk8s.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "frrk8s.fullname" . }}-controller
subjects:
- kind: ServiceAccount
name: {{ include "frrk8s.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "frrk8s.fullname" . }}-controller
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "frrk8s.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch","update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "frrk8s.fullname" . }}-controller
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "frrk8s.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "frrk8s.fullname" . }}-controller
subjects:
- kind: ServiceAccount
name: {{ include "frrk8s.serviceAccountName" . }}
{{ end -}}

View File

@ -0,0 +1,16 @@
{{- if .Values.frrk8s.serviceAccount.create }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "frrk8s.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "frrk8s.labels" . | nindent 4 }}
app.kubernetes.io/component: controller
{{- with .Values.frrk8s.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,128 @@
{{- if .Values.prometheus.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "frrk8s.labels" . | nindent 4 }}
app.kubernetes.io/component: frr-k8s
{{- if .Values.prometheus.serviceMonitor.additionalLabels }}
{{ toYaml .Values.prometheus.serviceMonitor.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.annotations }}
annotations:
{{ toYaml .Values.prometheus.serviceMonitor.annotations | indent 4 }}
{{- end }}
spec:
endpoints:
- port: "metricshttps"
honorLabels: true
{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }}
{{- end -}}
{{- if .Values.prometheus.serviceMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.interval }}
interval: {{ .Values.prometheus.serviceMonitor.interval }}
{{- end -}}
{{ if .Values.prometheus.secureMetricsPort }}
bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
scheme: "https"
{{- if .Values.prometheus.serviceMonitor.tlsConfig }}
tlsConfig:
{{ toYaml .Values.prometheus.serviceMonitor.tlsConfig | indent 8 }}
{{- end }}
{{ end }}
{{ if .Values.frrk8s.frr.secureMetricsPort }}
- port: "frrmetricshttps"
honorLabels: true
{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }}
{{- end -}}
{{- if .Values.prometheus.serviceMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.interval }}
interval: {{ .Values.prometheus.serviceMonitor.interval }}
{{- end }}
bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
scheme: "https"
{{- if .Values.prometheus.serviceMonitor.tlsConfig }}
tlsConfig:
{{ toYaml .Values.prometheus.serviceMonitor.tlsConfig | indent 8 }}
{{- end }}
{{- end }}
jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service
---
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: "true"
{{- if .Values.prometheus.serviceMonitor.annotations }}
{{ toYaml .Values.prometheus.serviceMonitor.annotations | indent 4 }}
{{- end }}
labels:
name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service
name: {{ template "frrk8s.fullname" . }}-frr-k8s-monitor-service
namespace: {{ .Release.Namespace | quote }}
spec:
selector:
{{- include "frrk8s.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: frr-k8s
clusterIP: None
ports:
- name: "metricshttps"
port: {{ .Values.prometheus.secureMetricsPort }}
targetPort: {{ .Values.prometheus.secureMetricsPort }}
- name: frrmetricshttps
port: {{ .Values.frrk8s.frr.secureMetricsPort }}
targetPort: {{ .Values.frrk8s.frr.secureMetricsPort }}
sessionAffinity: None
type: ClusterIP
---
{{- if .Values.prometheus.rbacPrometheus }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "frrk8s.fullname" . }}-prometheus
namespace: {{ .Release.Namespace | quote }}
rules:
- apiGroups:
- ""
resources:
- pods
- services
- endpoints
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ template "frrk8s.fullname" . }}-prometheus
namespace: {{ .Release.Namespace | quote }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "frrk8s.fullname" . }}-prometheus
subjects:
- kind: ServiceAccount
name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.serviceAccount }}
namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.namespace }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,163 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "frrk8s.fullname" . }}-webhook-server
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "frrk8s.labels" . | nindent 4 }}
app.kubernetes.io/component: frr-k8s-webhook-server
{{- range $key, $value := .Values.frrk8s.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
selector:
matchLabels:
app.kubernetes.io/component: frr-k8s-webhook-server
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: frr-k8s-webhook-server
labels:
app.kubernetes.io/component: frr-k8s-webhook-server
spec:
{{- if .Values.frrk8s.runtimeClassName }}
runtimeClassName: {{ .Values.frrk8s.runtimeClassName }}
{{- end }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.podSecurityContext }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- end }}
containers:
- command:
- /frr-k8s
args:
{{- with .Values.frrk8s.logLevel }}
- --log-level={{ . }}
{{- end }}
- "--webhook-mode=onlywebhook"
{{- if .Values.frrk8s.disableCertRotation }}
- "--disable-cert-rotation=true"
{{- end }}
{{- if .Values.frrk8s.restartOnRotatorSecretRefresh }}
- "--restart-on-rotator-secret-refresh=true"
{{- end }}
- "--namespace=$(NAMESPACE)"
- --health-probe-bind-address=:8081
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: {{ .Values.frrk8s.image.repository }}:{{ .Values.frrk8s.image.tag | default .Chart.AppVersion }}
{{- if .Values.frrk8s.image.pullPolicy }}
imagePullPolicy: {{ .Values.frrk8s.image.pullPolicy }}
{{- end }}
name: frr-k8s-webhook-server
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
{{- if .Values.frrk8s.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: {{ .Values.frrk8s.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.frrk8s.livenessProbe.periodSeconds }}
failureThreshold: {{ .Values.frrk8s.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.frrk8s.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: {{ .Values.frrk8s.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.frrk8s.readinessProbe.periodSeconds }}
failureThreshold: {{ .Values.frrk8s.readinessProbe.failureThreshold }}
{{- end }}
{{- with .Values.frrk8s.resources }}
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
volumeMounts:
- name: cert
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
{{- with .Values.frrk8s.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if or .Values.frrk8s.tolerateMaster .Values.frrk8s.tolerations }}
tolerations:
{{- if .Values.frrk8s.tolerateMaster }}
- key: node-role.kubernetes.io/master
effect: NoSchedule
operator: Exists
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
operator: Exists
{{- end }}
{{- with .Values.frrk8s.tolerations }}
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
{{- with .Values.frrk8s.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}
volumes:
- name: cert
secret:
defaultMode: 420
secretName: frr-k8s-webhook-server-cert
serviceAccountName: {{ template "frrk8s.serviceAccountName" . }}
terminationGracePeriodSeconds: 10
---
apiVersion: v1
kind: Secret
metadata:
name: frr-k8s-webhook-server-cert
namespace: {{ .Release.Namespace | quote }}
---
apiVersion: v1
kind: Service
metadata:
name: frr-k8s-webhook-service
namespace: {{ .Release.Namespace | quote }}
spec:
ports:
- port: 443
targetPort: 9443
selector:
app.kubernetes.io/component: frr-k8s-webhook-server
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: frr-k8s-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: frr-k8s-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-frrk8s-metallb-io-v1beta1-frrconfiguration
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: frrconfigurationsvalidationwebhook.metallb.io
rules:
- apiGroups:
- frrk8s.metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- frrconfigurations
sideEffects: None

View File

@ -0,0 +1,387 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"title": "Values",
"type": "object",
"definitions": {
"prometheusAlert": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"labels": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": [
"enabled"
]
},
"probe": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"failureThreshold": {
"type": "integer"
},
"initialDelaySeconds": {
"type": "integer"
},
"periodSeconds": {
"type": "integer"
},
"successThreshold": {
"type": "integer"
},
"timeoutSeconds": {
"type": "integer"
}
},
"required": [
"failureThreshold",
"initialDelaySeconds",
"periodSeconds",
"successThreshold",
"timeoutSeconds"
]
},
"component": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"logLevel": {
"type": "string",
"enum": [
"all",
"debug",
"info",
"warn",
"error",
"none"
]
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"pullPolicy": {
"anyOf": [
{
"type": "null"
},
{
"type": "string",
"enum": [
"Always",
"IfNotPresent",
"Never"
]
}
]
}
}
},
"serviceAccount": {
"type": "object",
"properties": {
"create": {
"type": "boolean"
},
"name": {
"type": "string"
},
"annotations": {
"type": "object"
}
}
},
"resources": {
"type": "object"
},
"nodeSelector": {
"type": "object"
},
"tolerations": {
"type": "array",
"items": {
"type": "object"
}
},
"priorityClassName": {
"type": "string"
},
"runtimeClassName": {
"type": "string"
},
"affinity": {
"type": "object"
},
"podAnnotations": {
"type": "object"
},
"livenessProbe": {
"$ref": "#/definitions/probe"
},
"readinessProbe": {
"$ref": "#/definitions/probe"
}
},
"required": [
"image",
"serviceAccount"
]
}
},
"properties": {
"imagePullSecrets": {
"description": "Secrets used for pulling images",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
},
"nameOverride": {
"description": "Override chart name",
"type": "string"
},
"fullNameOverride": {
"description": "Override fully qualified app name",
"type": "string"
},
"rbac": {
"description": "RBAC configuration",
"type": "object",
"properties": {
"create": {
"description": "Enable RBAC",
"type": "boolean"
}
}
},
"prometheus": {
"description": "Prometheus monitoring config",
"type": "object",
"properties": {
"scrapeAnnotations": {
"type": "boolean"
},
"metricsPort": {
"type": "integer"
},
"secureMetricsPort": {
"type": "integer"
},
"rbacPrometheus": {
"type": "boolean"
},
"serviceAccount": {
"type": "string"
},
"namespace": {
"type": "string"
},
"rbacProxy": {
"description": "kube-rbac-proxy configuration",
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},
"serviceMonitor": {
"description": "Prometheus Operator ServiceMonitors",
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"jobLabel": {
"type": "string"
},
"interval": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"metricRelabelings": {
"type": "array",
"items": {
"type": "object"
}
},
"relabelings": {
"type": "array",
"items": {
"type": "object"
}
}
}
}
},
"frrk8s": {
"allOf": [
{
"$ref": "#/definitions/component"
},
{
"description": "FRR-K8s controller",
"type": "object",
"properties": {
"tolerateMaster": {
"type": "boolean"
},
"updateStrategy": {
"type": "object",
"properties": {
"type": {
"type": "string"
}
},
"required": [
"type"
]
},
"runtimeClassName": {
"type": "string"
},
"secretName": {
"type": "string"
},
"frr": {
"description": "The FRR properties in the controller",
"type": "object",
"properties": {
"image": {
"$ref": "#/definitions/component/properties/image"
},
"metricsPort": {
"type": "integer"
},
"secureMetricsPort": {
"type": "integer"
},
"resources:": {
"type": "object"
}
},
"required": [
"enabled"
]
},
"command": {
"type": "string"
},
"reloader": {
"type": "object",
"properties": {
"resources": {
"type": "object"
}
}
},
"frrMetrics": {
"type": "object",
"properties": {
"resources": {
"type": "object"
}
}
}
},
"required": [
"tolerateMaster"
]
}
]
},
"crds": {
"description": "CRD configuration",
"type": "object",
"properties": {
"enabled": {
"description": "Enable CRDs",
"type": "boolean"
},
"validationFailurePolicy": {
"description": "Failure policy to use with validating webhooks",
"type": "string",
"enum": [
"Ignore",
"Fail"
]
}
}
}
},
"frrk8s": {
"allOf": [
{
"$ref": "#/definitions/component"
},
{
"description": "FRRk8s Controller",
"type": "object",
"properties": {
"strategy": {
"type": "object",
"properties": {
"type": {
"type": "string"
}
},
"required": [
"type"
]
},
"command": {
"type": "string"
},
"webhookMode": {
"type": "string"
}
}
}
]
}
},
"required": [
"frrk8s"
]
}

View File

@ -0,0 +1,176 @@
# Default values for frr-k8s.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
nameOverride: ""
fullnameOverride: ""
rbac:
# create specifies whether to install and use RBAC rules.
create: true
podSecurityContext:
seccompProfile:
type: RuntimeDefault
prometheus:
# scrape annotations specifies whether to add Prometheus metric
# auto-collection annotations to pods. See
# https://github.com/prometheus/prometheus/blob/release-2.1/documentation/examples/prometheus-kubernetes.yml
# for a corresponding Prometheus configuration. Alternatively, you
# may want to use the Prometheus Operator
# (https://github.com/coreos/prometheus-operator) for more powerful
# monitoring configuration. If you use the Prometheus operator, this
# can be left at false.
scrapeAnnotations: false
# bind addr frr-k8s will use for metrics
metricsBindAddress: 127.0.0.1
# port frr-k8s will listen on for metrics
metricsPort: 7572
# if set, enables rbac proxy on frr-k8s to expose
# the metrics via tls.
secureMetricsPort: 9140
# the name of the secret to be mounted in the frr-k8s pod
# to expose the metrics securely. If not present, a self signed
# certificate to be used.
metricsTLSSecret: ""
# prometheus doens't have the permission to scrape all namespaces so we give it permission to scrape metallb's one
rbacPrometheus: false
# the service account used by prometheus
# required when " .Values.prometheus.rbacPrometheus == true " and " prometheus.serviceMonitor.enabled=true "
serviceAccount: ""
# the namespace where prometheus is deployed
# required when " .Values.prometheus.rbacPrometheus == true " and " prometheus.serviceMonitor.enabled=true "
namespace: ""
# the image to be used for the kuberbacproxy container
rbacProxy:
repository: "registry.opensuse.org/isv/suse/edge/metallb/images/kube-rbac-proxy"
tag: "v0.18.0"
pullPolicy: IfNotPresent
# Prometheus Operator ServiceMonitors.
serviceMonitor:
# enable support for Prometheus Operator
enabled: false
additionalLabels: {}
# optional additional annotations for the controller serviceMonitor
annotations: {}
# optional tls configuration for the controller serviceMonitor, in case
# secure metrics are enabled.
tlsConfig:
insecureSkipVerify: true
# Job label for scrape target
jobLabel: "app.kubernetes.io/name"
# Scrape interval. If not set, the Prometheus default scrape interval is used.
interval:
# metric relabel configs to apply to samples before ingestion.
metricRelabelings: []
# - action: keep
# regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'
# sourceLabels: [__name__]
# relabel configs to apply to samples before ingestion.
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# target_label: nodename
# replacement: $1
# action: replace
# controller contains configuration specific to the FRRK8s controller
# daemonset.
frrk8s:
# -- Controller log level. Must be one of: `all`, `debug`, `info`, `warn`, `error` or `none`
logLevel: info
tolerateMaster: true
image:
repository: "registry.opensuse.org/isv/suse/edge/metallb/images/frr-k8s"
tag: "v0.0.14"
pullPolicy: IfNotPresent
## @param controller.updateStrategy.type FRR-K8s controller daemonset strategy type
## ref: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/
##
updateStrategy:
## StrategyType
## Can be set to RollingUpdate or OnDelete
##
type: RollingUpdate
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: true
# The name of the ServiceAccount to use. If not set and create is
# true, a name is generated using the fullname template
name: ""
annotations: {}
## Defines a secret name for the controller to generate a memberlist encryption secret
## By default secretName: {{ "metallb.fullname" }}-memberlist
##
# secretName:
resources: {}
# limits:
# cpu: 100m
# memory: 100Mi
nodeSelector: {}
tolerations: []
priorityClassName: ""
affinity: {}
## Selects which runtime class will be used by the pod.
runtimeClassName: ""
podAnnotations: {}
labels:
app: frr-k8s
healthPort: 8081
livenessProbe:
enabled: true
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
enabled: true
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
startupProbe:
enabled: true
failureThreshold: 30
periodSeconds: 5
## A comma separated list of cidrs we want always to block for incoming routes
alwaysBlock: ""
## Specifies whether the cert rotator works as part of the webhook.
disableCertRotation: false
## Specifies whether the pod restarts when the rotator refreshes the cert secret.
## Enabling this proved useful for the webhook's stability when it is redeployed multiple times in succession.
restartOnRotatorSecretRefresh: false
# frr contains configuration specific to the FRR container,
frr:
image:
repository: "registry.opensuse.org/isv/suse/edge/metallb/images/frr"
tag: "8.4"
pullPolicy: IfNotPresent
metricsBindAddress: 127.0.0.1
metricsPort: 7573
resources: {}
secureMetricsPort: 9141
reloader:
resources: {}
frrMetrics:
resources: {}
crds:
validationFailurePolicy: Fail

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,10 @@
apiVersion: v2
appVersion: v0.14.9
description: MetalLB CRDs
home: https://metallb.universe.tf
icon: https://metallb.universe.tf/images/logo/metallb-white.png
name: metallb-crds
sources:
- https://github.com/metallb/metallb
type: application
version: 0.14.8

Some files were not shown because too many files have changed in this diff Show More