From 37c961d380ea34cdc6c6908c6e9e83559a9abf95 Mon Sep 17 00:00:00 2001 From: Alberto Morgante Medina Date: Mon, 2 Dec 2024 17:11:14 +0100 Subject: [PATCH] make charts/html --- assets/metal3/metal3-0.9.1.tgz | Bin 0 -> 33986 bytes charts/metal3/0.9.1/.helmignore | 23 + charts/metal3/0.9.1/Chart.yaml | 26 + charts/metal3/0.9.1/README.md | 100 ++ charts/metal3/0.9.1/app-readme.md | 1 + .../charts/baremetal-operator/.helmignore | 23 + .../charts/baremetal-operator/Chart.yaml | 6 + .../crds/customresource-baremetalhosts.yaml | 1143 +++++++++++++++++ .../customresource-bmceventsubscriptions.yaml | 85 ++ .../crds/customresource-dataimages.yaml | 75 ++ .../crds/customresource-firmwareschemas.yaml | 90 ++ .../crds/customresource-hardwaredata.yaml | 211 +++ ...customresource-hostfirmwarecomponents.yaml | 178 +++ .../customresource-hostfirmwaresettings.yaml | 164 +++ .../customresource-preprovisioningimages.yaml | 183 +++ .../baremetal-operator/templates/NOTES.txt | 16 + .../baremetal-operator/templates/_helpers.tpl | 63 + .../templates/certificate.yaml | 14 + .../templates/clusterrole-manager.yaml | 186 +++ .../templates/clusterrole-metrics-reader.yaml | 11 + .../templates/clusterrole-proxy.yaml | 19 + .../templates/clusterrolebinding-manager.yaml | 14 + .../templates/clusterrolebinding-proxy.yaml | 14 + .../templates/configmap-ironic.yaml | 28 + .../templates/configmap.yaml | 19 + .../templates/deployment.yaml | 120 ++ .../baremetal-operator/templates/issuer.yaml | 8 + .../baremetal-operator/templates/role.yaml | 45 + .../templates/rolebinding.yaml | 13 + .../templates/service-controller-manager.yaml | 14 + .../templates/service-webhook.yaml | 13 + .../templates/serviceaccount.yaml | 12 + .../templates/tests/test-connection.yaml | 15 + .../validatingwebhookconfiguration.yaml | 51 + .../charts/baremetal-operator/values.yaml | 90 ++ charts/metal3/0.9.1/charts/ironic/.helmignore | 23 + charts/metal3/0.9.1/charts/ironic/Chart.yaml | 6 + charts/metal3/0.9.1/charts/ironic/README.md | 24 + .../0.9.1/charts/ironic/templates/NOTES.txt | 16 + .../charts/ironic/templates/_helpers.tpl | 85 ++ .../charts/ironic/templates/certificates.yaml | 43 + .../templates/configmap-ipa-downloader.yaml | 12 + .../charts/ironic/templates/configmap.yaml | 82 ++ .../charts/ironic/templates/deployment.yaml | 278 ++++ .../charts/ironic/templates/issuers.yaml | 16 + .../0.9.1/charts/ironic/templates/pvc.yaml | 26 + .../charts/ironic/templates/secret-tls.yaml | 16 + .../ironic/templates/secrets-basic-auth.yaml | 33 + .../charts/ironic/templates/service.yaml | 39 + .../ironic/templates/serviceaccount.yaml | 12 + charts/metal3/0.9.1/charts/ironic/values.yaml | 150 +++ .../metal3/0.9.1/charts/mariadb/.helmignore | 24 + charts/metal3/0.9.1/charts/mariadb/Chart.yaml | 6 + .../charts/mariadb/templates/_helpers.tpl | 64 + .../charts/mariadb/templates/configmap.yaml | 8 + .../charts/mariadb/templates/deployment.yaml | 85 ++ .../0.9.1/charts/mariadb/templates/pvc.yaml | 24 + .../charts/mariadb/templates/secret.yaml | 21 + .../mariadb/templates/service-account.yaml | 13 + .../charts/mariadb/templates/service.yaml | 14 + .../metal3/0.9.1/charts/mariadb/values.yaml | 67 + charts/metal3/0.9.1/charts/media/.helmignore | 23 + charts/metal3/0.9.1/charts/media/Chart.yaml | 6 + .../0.9.1/charts/media/templates/NOTES.txt | 22 + .../0.9.1/charts/media/templates/_helpers.tpl | 63 + .../charts/media/templates/deployment.yaml | 66 + .../0.9.1/charts/media/templates/hpa.yaml | 28 + .../0.9.1/charts/media/templates/ingress.yaml | 61 + .../media/templates/persistentvolume.yaml | 18 + .../templates/persistentvolumeclaim.yaml | 14 + .../0.9.1/charts/media/templates/service.yaml | 15 + .../media/templates/serviceaccount.yaml | 12 + .../charts/media/templates/storageclass.yaml | 9 + .../templates/tests/test-connection.yaml | 15 + charts/metal3/0.9.1/charts/media/values.yaml | 117 ++ charts/metal3/0.9.1/templates/NOTES.txt | 3 + charts/metal3/0.9.1/templates/_helpers.tpl | 62 + charts/metal3/0.9.1/values.yaml | 107 ++ index.html | 6 +- index.yaml | 30 + 80 files changed, 4934 insertions(+), 3 deletions(-) create mode 100644 assets/metal3/metal3-0.9.1.tgz create mode 100644 charts/metal3/0.9.1/.helmignore create mode 100644 charts/metal3/0.9.1/Chart.yaml create mode 100644 charts/metal3/0.9.1/README.md create mode 100644 charts/metal3/0.9.1/app-readme.md create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/.helmignore create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/Chart.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-bmceventsubscriptions.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-dataimages.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-firmwareschemas.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hardwaredata.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwarecomponents.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwaresettings.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-preprovisioningimages.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/NOTES.txt create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/_helpers.tpl create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/certificate.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-manager.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-metrics-reader.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-proxy.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-manager.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-proxy.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap-ironic.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/deployment.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/issuer.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/role.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/rolebinding.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/service-controller-manager.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/service-webhook.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/serviceaccount.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/tests/test-connection.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/templates/validatingwebhookconfiguration.yaml create mode 100644 charts/metal3/0.9.1/charts/baremetal-operator/values.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/.helmignore create mode 100644 charts/metal3/0.9.1/charts/ironic/Chart.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/README.md create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/NOTES.txt create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/_helpers.tpl create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/certificates.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/configmap-ipa-downloader.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/configmap.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/deployment.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/issuers.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/pvc.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/secret-tls.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/secrets-basic-auth.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/service.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/templates/serviceaccount.yaml create mode 100644 charts/metal3/0.9.1/charts/ironic/values.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/.helmignore create mode 100644 charts/metal3/0.9.1/charts/mariadb/Chart.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/_helpers.tpl create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/configmap.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/deployment.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/pvc.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/secret.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/service-account.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/templates/service.yaml create mode 100644 charts/metal3/0.9.1/charts/mariadb/values.yaml create mode 100644 charts/metal3/0.9.1/charts/media/.helmignore create mode 100644 charts/metal3/0.9.1/charts/media/Chart.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/NOTES.txt create mode 100644 charts/metal3/0.9.1/charts/media/templates/_helpers.tpl create mode 100644 charts/metal3/0.9.1/charts/media/templates/deployment.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/hpa.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/ingress.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/persistentvolume.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/persistentvolumeclaim.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/service.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/serviceaccount.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/storageclass.yaml create mode 100644 charts/metal3/0.9.1/charts/media/templates/tests/test-connection.yaml create mode 100644 charts/metal3/0.9.1/charts/media/values.yaml create mode 100644 charts/metal3/0.9.1/templates/NOTES.txt create mode 100644 charts/metal3/0.9.1/templates/_helpers.tpl create mode 100644 charts/metal3/0.9.1/values.yaml diff --git a/assets/metal3/metal3-0.9.1.tgz b/assets/metal3/metal3-0.9.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..98df0397bb6b9b3a84f7589b05f50838e9ed48ea GIT binary patch literal 33986 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 literal 0 HcmV?d00001 diff --git a/charts/metal3/0.9.1/.helmignore b/charts/metal3/0.9.1/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/metal3/0.9.1/.helmignore @@ -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/ diff --git a/charts/metal3/0.9.1/Chart.yaml b/charts/metal3/0.9.1/Chart.yaml new file mode 100644 index 00000000..d1d52e33 --- /dev/null +++ b/charts/metal3/0.9.1/Chart.yaml @@ -0,0 +1,26 @@ +apiVersion: v2 +appVersion: 1.16.0 +dependencies: +- alias: metal3-baremetal-operator + name: baremetal-operator + repository: file://./charts/baremetal-operator + version: 0.6.0 +- alias: metal3-ironic + name: ironic + repository: file://./charts/ironic + version: 0.9.0 +- alias: metal3-mariadb + condition: global.enable_mariadb + name: mariadb + repository: file://./charts/mariadb + version: 0.5.4 +- alias: metal3-media + condition: global.enable_metal3_media_server + name: media + repository: file://./charts/media + version: 0.6.0 +description: A Helm chart that installs all of the dependencies needed for Metal3 +icon: https://github.com/cncf/artwork/raw/master/projects/metal3/icon/color/metal3-icon-color.svg +name: metal3 +type: application +version: 0.9.1 diff --git a/charts/metal3/0.9.1/README.md b/charts/metal3/0.9.1/README.md new file mode 100644 index 00000000..e288220b --- /dev/null +++ b/charts/metal3/0.9.1/README.md @@ -0,0 +1,100 @@ +# Prerequisites +There are two dependencies that are not managed through the metal3 chart because are related to applications that have a cluster-wide scope: `cert-manager` and a LoadBalancer Service provider such as `metallb` or `kube-vip`. + +## Cert Manager +In order to successfully deploy metal3 the cluster must have already installed the `cert-manager`. + +You can install it through `helm` with: +```bash +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set installCRDs=true +``` +, or via `kubectl` with: +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.1/cert-manager.yaml +``` + +## MetalLB (Optional) +Ironic currently requires a staticIP address and MetalLB is one option to achieve that. + +1. If K3s is used as Kubernetes distribution, then it should be started with `--disable=servicelb` flag. Ref https://metallb.universe.tf/configuration/k3s/ +2. Find 1 free IP address in the network. +3. Install `MetalLB` through `helm` with: + +```bash +helm repo add suse-edge https://suse-edge.github.io/charts +helm install \ + metallb suse-edge/metallb \ + --namespace metallb-system \ + --create-namespace +``` + +4. Provide the IP pool configuration with: + +```bash +export STATIC_IRONIC_IP= + +cat <<-EOF | kubectl apply -f - +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: ironic-ip-pool + namespace: metallb-system +spec: + addresses: + - ${STATIC_IRONIC_IP}/32 + serviceAllocation: + priority: 100 + serviceSelectors: + - matchExpressions: + - {key: app.kubernetes.io/name, operator: In, values: [metal3-ironic]} +EOF + +cat <<-EOF | kubectl apply -f - +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: ironic-ip-pool-l2-adv + namespace: metallb-system +spec: + ipAddressPools: + - ironic-ip-pool +EOF +``` + +5. Create new values.yaml file that will override some of the default properties: + +```bash +TMP_DIR=$(mktemp -d) +cat > ${TMP_DIR}/values.yaml << EOF +global: + ironicIP: "" +EOF +``` + +# Install + +```bash +helm install \ + metal3 suse-edge/metal3 \ + --namespace metal3-system \ + --create-namespace + -f ${TMP_DIR}/values.yaml +``` + +# How to upgrade the chart +1. Run `helm dependency update .` in this chart to download/update the dependent charts. + +2. Identify the appropriate subchart values settings and create an appropriate override values YAML file. + * Ensure that the relevant ironic and baremetal-operator settings match. + +3. Install the chart using a command like the following: + +```console +$ helm upgrade heavy-metal . --namespace metal-cubed --create-namespace --install --values ~/overrides.yaml +``` diff --git a/charts/metal3/0.9.1/app-readme.md b/charts/metal3/0.9.1/app-readme.md new file mode 100644 index 00000000..ffa1c862 --- /dev/null +++ b/charts/metal3/0.9.1/app-readme.md @@ -0,0 +1 @@ +The metal3 chart is a parent chart that installs all of the other charts that a metal3 deployment needs, but doesn't actually deploy any services itself. \ No newline at end of file diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/.helmignore b/charts/metal3/0.9.1/charts/baremetal-operator/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/.helmignore @@ -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/ diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/Chart.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/Chart.yaml new file mode 100644 index 00000000..9b3d7c33 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 0.8.0 +description: A Helm chart for baremetal-operator, used by Metal3 +name: baremetal-operator +type: application +version: 0.6.0 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml new file mode 100644 index 00000000..b5996681 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml @@ -0,0 +1,1143 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: baremetal-operator-system/baremetal-operator-serving-cert + controller-gen.kubebuilder.io/version: v0.12.1 + labels: + clusterctl.cluster.x-k8s.io: "" + name: baremetalhosts.metal3.io +spec: + group: metal3.io + names: + kind: BareMetalHost + listKind: BareMetalHostList + plural: baremetalhosts + shortNames: + - bmh + - bmhost + singular: baremetalhost + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Operational status + jsonPath: .status.operationalStatus + name: Status + priority: 1 + type: string + - description: Provisioning status + jsonPath: .status.provisioning.state + name: State + type: string + - description: Consumer using this host + jsonPath: .spec.consumerRef.name + name: Consumer + type: string + - description: Address of management controller + jsonPath: .spec.bmc.address + name: BMC + priority: 1 + type: string + - description: Whether the host is online or not + jsonPath: .spec.online + name: Online + type: string + - description: Type of the most recent error + jsonPath: .status.errorType + name: Error + type: string + - description: Time duration since creation of BaremetalHost + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BareMetalHost is the Schema for the baremetalhosts 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: BareMetalHostSpec defines the desired state of BareMetalHost. + properties: + architecture: + description: CPU architecture of the host, e.g. "x86_64" or "aarch64". + If unset, eventually populated by inspection. + type: string + automatedCleaningMode: + default: metadata + description: When set to disabled, automated cleaning will be avoided + during provisioning and deprovisioning. + enum: + - metadata + - disabled + type: string + bmc: + description: How do we connect to the BMC? + properties: + address: + description: Address holds the URL for accessing the controller + on the network. + type: string + credentialsName: + description: The name of the secret containing the BMC credentials + (requires keys "username" and "password"). + type: string + disableCertificateVerification: + description: DisableCertificateVerification disables verification + of server certificates when using HTTPS to connect to the BMC. + This is required when the server certificate is self-signed, + but is insecure because it allows a man-in-the-middle to intercept + the connection. + type: boolean + required: + - address + - credentialsName + type: object + bootMACAddress: + description: Which MAC address will PXE boot? This is optional for + some types, but required for libvirt VMs driven by vbmc. + pattern: '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' + type: string + bootMode: + description: Select the method of initializing the hardware during + boot. Defaults to UEFI. + enum: + - UEFI + - UEFISecureBoot + - legacy + type: string + consumerRef: + description: ConsumerRef can be used to store information about something + that is using a host. When it is not empty, the host is considered + "in use". + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + customDeploy: + description: A custom deploy procedure. + properties: + method: + description: Custom deploy method name. This name is specific + to the deploy ramdisk used. If you don't have a custom deploy + ramdisk, you shouldn't use CustomDeploy. + type: string + required: + - method + type: object + description: + description: Description is a human-entered text used to help identify + the host + type: string + externallyProvisioned: + description: ExternallyProvisioned means something else is managing + the image running on the host and the operator should only manage + the power status and hardware inventory inspection. If the Image + field is filled in, this field is ignored. + type: boolean + firmware: + description: BIOS configuration for bare metal server + properties: + simultaneousMultithreadingEnabled: + description: 'Allows a single physical processor core to appear + as several logical processors. This supports following options: + true, false.' + enum: + - true + - false + type: boolean + sriovEnabled: + description: 'SR-IOV support enables a hypervisor to create virtual + instances of a PCI-express device, potentially increasing performance. + This supports following options: true, false.' + enum: + - true + - false + type: boolean + virtualizationEnabled: + description: 'Supports the virtualization of platform hardware. + This supports following options: true, false.' + enum: + - true + - false + type: boolean + type: object + hardwareProfile: + description: What is the name of the hardware profile for this host? + Hardware profiles are deprecated and should not be used. Use the + separate fields Architecture and RootDeviceHints instead. Set to + "empty" to prepare for the future version of the API without hardware + profiles. + type: string + image: + description: Image holds the details of the image to be provisioned. + properties: + checksum: + description: Checksum is the checksum for the image. + type: string + checksumType: + description: ChecksumType is the checksum algorithm for the image, + e.g md5, sha256 or sha512. The special value "auto" can be used + to detect the algorithm from the checksum. If missing, MD5 is + used. If in doubt, use "auto". + enum: + - md5 + - sha256 + - sha512 + - auto + type: string + format: + description: DiskFormat contains the format of the image (raw, + qcow2, ...). Needs to be set to raw for raw images streaming. + Note live-iso means an iso referenced by the url will be live-booted + and not deployed to disk, and in this case the checksum options + are not required and if specified will be ignored. + enum: + - raw + - qcow2 + - vdi + - vmdk + - live-iso + type: string + url: + description: URL is a location of an image to deploy. + type: string + required: + - url + type: object + metaData: + description: MetaData holds the reference to the Secret containing + host metadata (e.g. meta_data.json) which is passed to the Config + Drive. + 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 + networkData: + description: NetworkData holds the reference to the Secret containing + network configuration (e.g content of network_data.json) which is + passed to the Config Drive. + 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 + online: + description: Should the server be online? + type: boolean + preprovisioningNetworkDataName: + description: PreprovisioningNetworkDataName is the name of the Secret + in the local namespace containing network configuration (e.g content + of network_data.json) which is passed to the preprovisioning image, + and to the Config Drive if not overridden by specifying NetworkData. + type: string + raid: + description: RAID configuration for bare metal server + properties: + hardwareRAIDVolumes: + description: The list of logical disks for hardware RAID, if rootDeviceHints + isn't used, first volume is root volume. You can set the value + of this field to `[]` to clear all the hardware RAID configurations. + items: + description: HardwareRAIDVolume defines the desired configuration + of volume in hardware RAID. + properties: + controller: + description: The name of the RAID controller to use + type: string + level: + description: 'RAID level for the logical disk. The following + levels are supported: 0;1;2;5;6;1+0;5+0;6+0.' + enum: + - "0" + - "1" + - "2" + - "5" + - "6" + - 1+0 + - 5+0 + - 6+0 + type: string + name: + description: Name of the volume. Should be unique within + the Node. If not specified, volume name will be auto-generated. + maxLength: 64 + type: string + numberOfPhysicalDisks: + description: Integer, number of physical disks to use for + the logical disk. Defaults to minimum number of disks + required for the particular RAID level. + minimum: 1 + type: integer + physicalDisks: + description: Optional list of physical disk names to be + used for the Hardware RAID volumes. The disk names are + interpreted by the Hardware RAID controller, and the format + is hardware specific. + items: + type: string + type: array + rotational: + description: Select disks with only rotational or solid-state + storage + type: boolean + sizeGibibytes: + description: Size (Integer) of the logical disk to be created + in GiB. If unspecified or set be 0, the maximum capacity + of disk will be used for logical disk. + minimum: 0 + type: integer + required: + - level + type: object + nullable: true + type: array + softwareRAIDVolumes: + description: The list of logical disks for software RAID, if rootDeviceHints + isn't used, first volume is root volume. If HardwareRAIDVolumes + is set this item will be invalid. The number of created Software + RAID devices must be 1 or 2. If there is only one Software RAID + device, it has to be a RAID-1. If there are two, the first one + has to be a RAID-1, while the RAID level for the second one + can be 0, 1, or 1+0. As the first RAID device will be the deployment + device, enforcing a RAID-1 reduces the risk of ending up with + a non-booting node in case of a disk failure. Software RAID + will always be deleted. + items: + description: SoftwareRAIDVolume defines the desired configuration + of volume in software RAID. + properties: + level: + description: 'RAID level for the logical disk. The following + levels are supported: 0;1;1+0.' + enum: + - "0" + - "1" + - 1+0 + type: string + physicalDisks: + description: A list of device hints, the number of items + should be greater than or equal to 2. + items: + description: RootDeviceHints holds the hints for specifying + the storage location for the root filesystem for the + image. + properties: + deviceName: + description: A Linux device name like "/dev/vda", + or a by-path link to it like "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0". + The hint must match the actual value exactly. + type: string + hctl: + description: A SCSI bus address like 0:0:0:0. The + hint must match the actual value exactly. + type: string + minSizeGigabytes: + description: The minimum size of the device in Gigabytes. + minimum: 0 + type: integer + model: + description: A vendor-specific device identifier. + The hint can be a substring of the actual value. + type: string + rotational: + description: True if the device should use spinning + media, false otherwise. + type: boolean + serialNumber: + description: Device serial number. The hint must match + the actual value exactly. + type: string + vendor: + description: The name of the vendor or manufacturer + of the device. The hint can be a substring of the + actual value. + type: string + wwn: + description: Unique storage identifier. The hint must + match the actual value exactly. + type: string + wwnVendorExtension: + description: Unique vendor storage identifier. The + hint must match the actual value exactly. + type: string + wwnWithExtension: + description: Unique storage identifier with the vendor + extension appended. The hint must match the actual + value exactly. + type: string + type: object + minItems: 2 + type: array + sizeGibibytes: + description: Size (Integer) of the logical disk to be created + in GiB. If unspecified or set be 0, the maximum capacity + of disk will be used for logical disk. + minimum: 0 + type: integer + required: + - level + type: object + maxItems: 2 + nullable: true + type: array + type: object + rootDeviceHints: + description: Provide guidance about how to choose the device for the + image being provisioned. + properties: + deviceName: + description: A Linux device name like "/dev/vda", or a by-path + link to it like "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0". + The hint must match the actual value exactly. + type: string + hctl: + description: A SCSI bus address like 0:0:0:0. The hint must match + the actual value exactly. + type: string + minSizeGigabytes: + description: The minimum size of the device in Gigabytes. + minimum: 0 + type: integer + model: + description: A vendor-specific device identifier. The hint can + be a substring of the actual value. + type: string + rotational: + description: True if the device should use spinning media, false + otherwise. + type: boolean + serialNumber: + description: Device serial number. The hint must match the actual + value exactly. + type: string + vendor: + description: The name of the vendor or manufacturer of the device. + The hint can be a substring of the actual value. + type: string + wwn: + description: Unique storage identifier. The hint must match the + actual value exactly. + type: string + wwnVendorExtension: + description: Unique vendor storage identifier. The hint must match + the actual value exactly. + type: string + wwnWithExtension: + description: Unique storage identifier with the vendor extension + appended. The hint must match the actual value exactly. + type: string + type: object + taints: + description: Taints is the full, authoritative list of taints to apply + to the corresponding Machine. This list will overwrite any modifications + made to the Machine on an ongoing basis. + items: + description: The node this Taint is attached to has the "effect" + on any pod that does not tolerate the Taint. + properties: + effect: + description: Required. The effect of the taint on pods that + do not tolerate the taint. Valid effects are NoSchedule, PreferNoSchedule + and NoExecute. + type: string + key: + description: Required. The taint key to be applied to a node. + type: string + timeAdded: + description: TimeAdded represents the time at which the taint + was added. It is only written for NoExecute taints. + format: date-time + type: string + value: + description: The taint value corresponding to the taint key. + type: string + required: + - effect + - key + type: object + type: array + userData: + description: UserData holds the reference to the Secret containing + the user data to be passed to the host before it boots. + 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 + required: + - online + type: object + status: + description: BareMetalHostStatus defines the observed state of BareMetalHost. + properties: + errorCount: + default: 0 + description: ErrorCount records how many times the host has encoutered + an error since the last successful operation + type: integer + errorMessage: + description: the last error message reported by the provisioning subsystem + type: string + errorType: + description: ErrorType indicates the type of failure encountered when + the OperationalStatus is OperationalStatusError + enum: + - provisioned registration error + - registration error + - inspection error + - preparation error + - provisioning error + - power management error + type: string + goodCredentials: + description: the last credentials we were able to validate as working + properties: + credentials: + description: SecretReference represents a Secret Reference. It + has enough information to retrieve secret in any namespace + 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 + credentialsVersion: + type: string + type: object + hardware: + description: The hardware discovered to exist on the host. + 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 + hardwareProfile: + description: The name of the profile matching the hardware details. + Hardware profiles are deprecated and should not be relied on. + type: string + lastUpdated: + description: LastUpdated identifies when this status was last observed. + format: date-time + type: string + operationHistory: + description: OperationHistory holds information about operations performed + on this host. + properties: + deprovision: + description: OperationMetric contains metadata about an operation + (inspection, provisioning, etc.) used for tracking metrics. + properties: + end: + format: date-time + nullable: true + type: string + start: + format: date-time + nullable: true + type: string + type: object + inspect: + description: OperationMetric contains metadata about an operation + (inspection, provisioning, etc.) used for tracking metrics. + properties: + end: + format: date-time + nullable: true + type: string + start: + format: date-time + nullable: true + type: string + type: object + provision: + description: OperationMetric contains metadata about an operation + (inspection, provisioning, etc.) used for tracking metrics. + properties: + end: + format: date-time + nullable: true + type: string + start: + format: date-time + nullable: true + type: string + type: object + register: + description: OperationMetric contains metadata about an operation + (inspection, provisioning, etc.) used for tracking metrics. + properties: + end: + format: date-time + nullable: true + type: string + start: + format: date-time + nullable: true + type: string + type: object + type: object + operationalStatus: + description: OperationalStatus holds the status of the host + enum: + - "" + - OK + - discovered + - error + - delayed + - detached + type: string + poweredOn: + description: indicator for whether or not the host is powered on + type: boolean + provisioning: + description: Information tracked by the provisioner. + properties: + ID: + description: The machine's UUID from the underlying provisioning + tool + type: string + bootMode: + description: BootMode indicates the boot mode used to provision + the node + enum: + - UEFI + - UEFISecureBoot + - legacy + type: string + customDeploy: + description: Custom deploy procedure applied to the host. + properties: + method: + description: Custom deploy method name. This name is specific + to the deploy ramdisk used. If you don't have a custom deploy + ramdisk, you shouldn't use CustomDeploy. + type: string + required: + - method + type: object + firmware: + description: The Bios set by the user + properties: + simultaneousMultithreadingEnabled: + description: 'Allows a single physical processor core to appear + as several logical processors. This supports following options: + true, false.' + enum: + - true + - false + type: boolean + sriovEnabled: + description: 'SR-IOV support enables a hypervisor to create + virtual instances of a PCI-express device, potentially increasing + performance. This supports following options: true, false.' + enum: + - true + - false + type: boolean + virtualizationEnabled: + description: 'Supports the virtualization of platform hardware. + This supports following options: true, false.' + enum: + - true + - false + type: boolean + type: object + image: + description: Image holds the details of the last image successfully + provisioned to the host. + properties: + checksum: + description: Checksum is the checksum for the image. + type: string + checksumType: + description: ChecksumType is the checksum algorithm for the + image, e.g md5, sha256 or sha512. The special value "auto" + can be used to detect the algorithm from the checksum. If + missing, MD5 is used. If in doubt, use "auto". + enum: + - md5 + - sha256 + - sha512 + - auto + type: string + format: + description: DiskFormat contains the format of the image (raw, + qcow2, ...). Needs to be set to raw for raw images streaming. + Note live-iso means an iso referenced by the url will be + live-booted and not deployed to disk, and in this case the + checksum options are not required and if specified will + be ignored. + enum: + - raw + - qcow2 + - vdi + - vmdk + - live-iso + type: string + url: + description: URL is a location of an image to deploy. + type: string + required: + - url + type: object + raid: + description: The Raid set by the user + properties: + hardwareRAIDVolumes: + description: The list of logical disks for hardware RAID, + if rootDeviceHints isn't used, first volume is root volume. + You can set the value of this field to `[]` to clear all + the hardware RAID configurations. + items: + description: HardwareRAIDVolume defines the desired configuration + of volume in hardware RAID. + properties: + controller: + description: The name of the RAID controller to use + type: string + level: + description: 'RAID level for the logical disk. The following + levels are supported: 0;1;2;5;6;1+0;5+0;6+0.' + enum: + - "0" + - "1" + - "2" + - "5" + - "6" + - 1+0 + - 5+0 + - 6+0 + type: string + name: + description: Name of the volume. Should be unique within + the Node. If not specified, volume name will be auto-generated. + maxLength: 64 + type: string + numberOfPhysicalDisks: + description: Integer, number of physical disks to use + for the logical disk. Defaults to minimum number of + disks required for the particular RAID level. + minimum: 1 + type: integer + physicalDisks: + description: Optional list of physical disk names to + be used for the Hardware RAID volumes. The disk names + are interpreted by the Hardware RAID controller, and + the format is hardware specific. + items: + type: string + type: array + rotational: + description: Select disks with only rotational or solid-state + storage + type: boolean + sizeGibibytes: + description: Size (Integer) of the logical disk to be + created in GiB. If unspecified or set be 0, the maximum + capacity of disk will be used for logical disk. + minimum: 0 + type: integer + required: + - level + type: object + nullable: true + type: array + softwareRAIDVolumes: + description: The list of logical disks for software RAID, + if rootDeviceHints isn't used, first volume is root volume. + If HardwareRAIDVolumes is set this item will be invalid. + The number of created Software RAID devices must be 1 or + 2. If there is only one Software RAID device, it has to + be a RAID-1. If there are two, the first one has to be a + RAID-1, while the RAID level for the second one can be 0, + 1, or 1+0. As the first RAID device will be the deployment + device, enforcing a RAID-1 reduces the risk of ending up + with a non-booting node in case of a disk failure. Software + RAID will always be deleted. + items: + description: SoftwareRAIDVolume defines the desired configuration + of volume in software RAID. + properties: + level: + description: 'RAID level for the logical disk. The following + levels are supported: 0;1;1+0.' + enum: + - "0" + - "1" + - 1+0 + type: string + physicalDisks: + description: A list of device hints, the number of items + should be greater than or equal to 2. + items: + description: RootDeviceHints holds the hints for specifying + the storage location for the root filesystem for + the image. + properties: + deviceName: + description: A Linux device name like "/dev/vda", + or a by-path link to it like "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0". + The hint must match the actual value exactly. + type: string + hctl: + description: A SCSI bus address like 0:0:0:0. + The hint must match the actual value exactly. + type: string + minSizeGigabytes: + description: The minimum size of the device in + Gigabytes. + minimum: 0 + type: integer + model: + description: A vendor-specific device identifier. + The hint can be a substring of the actual value. + type: string + rotational: + description: True if the device should use spinning + media, false otherwise. + type: boolean + serialNumber: + description: Device serial number. The hint must + match the actual value exactly. + type: string + vendor: + description: The name of the vendor or manufacturer + of the device. The hint can be a substring of + the actual value. + type: string + wwn: + description: Unique storage identifier. The hint + must match the actual value exactly. + type: string + wwnVendorExtension: + description: Unique vendor storage identifier. + The hint must match the actual value exactly. + type: string + wwnWithExtension: + description: Unique storage identifier with the + vendor extension appended. The hint must match + the actual value exactly. + type: string + type: object + minItems: 2 + type: array + sizeGibibytes: + description: Size (Integer) of the logical disk to be + created in GiB. If unspecified or set be 0, the maximum + capacity of disk will be used for logical disk. + minimum: 0 + type: integer + required: + - level + type: object + maxItems: 2 + nullable: true + type: array + type: object + rootDeviceHints: + description: The RootDevicehints set by the user + properties: + deviceName: + description: A Linux device name like "/dev/vda", or a by-path + link to it like "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:2:0:0". + The hint must match the actual value exactly. + type: string + hctl: + description: A SCSI bus address like 0:0:0:0. The hint must + match the actual value exactly. + type: string + minSizeGigabytes: + description: The minimum size of the device in Gigabytes. + minimum: 0 + type: integer + model: + description: A vendor-specific device identifier. The hint + can be a substring of the actual value. + type: string + rotational: + description: True if the device should use spinning media, + false otherwise. + type: boolean + serialNumber: + description: Device serial number. The hint must match the + actual value exactly. + type: string + vendor: + description: The name of the vendor or manufacturer of the + device. The hint can be a substring of the actual value. + type: string + wwn: + description: Unique storage identifier. The hint must match + the actual value exactly. + type: string + wwnVendorExtension: + description: Unique vendor storage identifier. The hint must + match the actual value exactly. + type: string + wwnWithExtension: + description: Unique storage identifier with the vendor extension + appended. The hint must match the actual value exactly. + type: string + type: object + state: + description: An indiciator for what the provisioner is doing with + the host. + type: string + required: + - ID + - state + type: object + triedCredentials: + description: the last credentials we sent to the provisioning backend + properties: + credentials: + description: SecretReference represents a Secret Reference. It + has enough information to retrieve secret in any namespace + 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 + credentialsVersion: + type: string + type: object + required: + - errorCount + - errorMessage + - operationalStatus + - poweredOn + - provisioning + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-bmceventsubscriptions.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-bmceventsubscriptions.yaml new file mode 100644 index 00000000..9aed81fa --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-bmceventsubscriptions.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-dataimages.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-dataimages.yaml new file mode 100644 index 00000000..bbaec875 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-dataimages.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-firmwareschemas.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-firmwareschemas.yaml new file mode 100644 index 00000000..3d933552 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-firmwareschemas.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hardwaredata.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hardwaredata.yaml new file mode 100644 index 00000000..d2821ed3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hardwaredata.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwarecomponents.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwarecomponents.yaml new file mode 100644 index 00000000..d79382fe --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwarecomponents.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwaresettings.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwaresettings.yaml new file mode 100644 index 00000000..2166b859 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-hostfirmwaresettings.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-preprovisioningimages.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-preprovisioningimages.yaml new file mode 100644 index 00000000..c3e4f5ca --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/crds/customresource-preprovisioningimages.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/NOTES.txt b/charts/metal3/0.9.1/charts/baremetal-operator/templates/NOTES.txt new file mode 100644 index 00000000..47f9ee7e --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/NOTES.txt @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/_helpers.tpl b/charts/metal3/0.9.1/charts/baremetal-operator/templates/_helpers.tpl new file mode 100644 index 00000000..50c6823b --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/_helpers.tpl @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/certificate.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/certificate.yaml new file mode 100644 index 00000000..2d424b75 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/certificate.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-manager.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-manager.yaml new file mode 100644 index 00000000..157d7a32 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-manager.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-metrics-reader.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-metrics-reader.yaml new file mode 100644 index 00000000..1bcde61d --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-metrics-reader.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-proxy.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-proxy.yaml new file mode 100644 index 00000000..96d62086 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrole-proxy.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-manager.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-manager.yaml new file mode 100644 index 00000000..b02f6ba6 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-manager.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-proxy.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-proxy.yaml new file mode 100644 index 00000000..4745ace8 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/clusterrolebinding-proxy.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap-ironic.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap-ironic.yaml new file mode 100644 index 00000000..69609275 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap-ironic.yaml @@ -0,0 +1,28 @@ + {{- $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" }} + {{- $ironicBootHost := print $ironicIP ":6180" }} + {{- $ironicCacheHost := print $ironicIP ":6180" }} + +apiVersion: v1 +data: + IRONIC_ENDPOINT: "{{ $protocol }}://{{ $ironicApiHost }}/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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap.yaml new file mode 100644 index 00000000..db575684 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/configmap.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/deployment.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/deployment.yaml new file mode 100644 index 00000000..8cd24247 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/deployment.yaml @@ -0,0 +1,120 @@ +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 + {{- 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 + {{- end }} + {{- if .Values.global.enable_tls }} + - name: cacert + secret: + secretName: ironic-cacert + {{- end }} + {{- with .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/issuer.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/issuer.yaml new file mode 100644 index 00000000..9b12180f --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/issuer.yaml @@ -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: {} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/role.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/role.yaml new file mode 100644 index 00000000..313066a4 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/role.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/rolebinding.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/rolebinding.yaml new file mode 100644 index 00000000..4492103e --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/rolebinding.yaml @@ -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" . }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-controller-manager.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-controller-manager.yaml new file mode 100644 index 00000000..1578efaa --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-controller-manager.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-webhook.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-webhook.yaml new file mode 100644 index 00000000..7c947f9d --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/service-webhook.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/serviceaccount.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/serviceaccount.yaml new file mode 100644 index 00000000..4eab8805 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/serviceaccount.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/tests/test-connection.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/tests/test-connection.yaml new file mode 100644 index 00000000..7c003b50 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/tests/test-connection.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/templates/validatingwebhookconfiguration.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/templates/validatingwebhookconfiguration.yaml new file mode 100644 index 00000000..55746b9e --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/templates/validatingwebhookconfiguration.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/baremetal-operator/values.yaml b/charts/metal3/0.9.1/charts/baremetal-operator/values.yaml new file mode 100644 index 00000000..61b058f7 --- /dev/null +++ b/charts/metal3/0.9.1/charts/baremetal-operator/values.yaml @@ -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.8.0" + rbacProxy: + repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/kube-rbac-proxy + pullPolicy: IfNotPresent + tag: "0.18.1" + +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" diff --git a/charts/metal3/0.9.1/charts/ironic/.helmignore b/charts/metal3/0.9.1/charts/ironic/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/.helmignore @@ -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/ diff --git a/charts/metal3/0.9.1/charts/ironic/Chart.yaml b/charts/metal3/0.9.1/charts/ironic/Chart.yaml new file mode 100644 index 00000000..b978dcf8 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 26.1.2 +description: A Helm chart for Ironic, used by Metal3 +name: ironic +type: application +version: 0.9.0 diff --git a/charts/metal3/0.9.1/charts/ironic/README.md b/charts/metal3/0.9.1/charts/ironic/README.md new file mode 100644 index 00000000..860ebcab --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/README.md @@ -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. diff --git a/charts/metal3/0.9.1/charts/ironic/templates/NOTES.txt b/charts/metal3/0.9.1/charts/ironic/templates/NOTES.txt new file mode 100644 index 00000000..eb10ff46 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/NOTES.txt @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/_helpers.tpl b/charts/metal3/0.9.1/charts/ironic/templates/_helpers.tpl new file mode 100644 index 00000000..372e8f01 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/_helpers.tpl @@ -0,0 +1,85 @@ +{{/* +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 +{{- if .Values.global.enable_vmedia_tls }} +- name: cert-ironic-vmedia-ca + mountPath: "/certs/ca/vmedia" + readOnly: true +{{- end }} +{{- end }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/certificates.yaml b/charts/metal3/0.9.1/charts/ironic/templates/certificates.yaml new file mode 100644 index 00000000..ee486b06 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/certificates.yaml @@ -0,0 +1,43 @@ +{{- 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 +{{- 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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/configmap-ipa-downloader.yaml b/charts/metal3/0.9.1/charts/ironic/templates/configmap-ipa-downloader.yaml new file mode 100644 index 00000000..0536c000 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/configmap-ipa-downloader.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/configmap.yaml b/charts/metal3/0.9.1/charts/ironic/templates/configmap.yaml new file mode 100644 index 00000000..5c369c92 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/configmap.yaml @@ -0,0 +1,82 @@ +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" }} + {{- $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: "false" + IRONIC_API_BASE_URL: {{ $protocol }}://{{ $ironicApiHost }} + IRONIC_API_HOST: {{ $ironicApiHost }} + IRONIC_API_HTTPD_SERVER_NAME: {{ $ironicApiHost }} + IRONIC_ENDPOINT: {{ $protocol }}://{{ $ironicApiHost }}/v1/ + # 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_ILO_USE_SWIFT: "false" + IRONIC_ILO_USE_WEB_SERVER_FOR_IMAGES: "true" + IRONIC_FAST_TRACK: "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" + {{- 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" + {{- end }} + {{- if .Values.global.enable_mariadb }} + MARIADB_HOST: {{ .Values.global.databaseServiceName }}.{{ .Release.Namespace }}.svc.cluster.local + IRONIC_USE_MARIADB: "true" + {{- else }} + IRONIC_USE_MARIADB: "false" + {{- end }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/deployment.yaml b/charts/metal3/0.9.1/charts/ironic/templates/deployment.yaml new file mode 100644 index 00000000..f49ba435 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/deployment.yaml @@ -0,0 +1,278 @@ +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: ["sh", "-c", "curl -sSfk https://127.0.0.1:6385"] + 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: ["sh", "-c", "curl -sSfk https://127.0.0.1:6385"] + 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 + {{- 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-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 }} + {{- if .Values.global.enable_mariadb }} + - name: MARIADB_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: ironic-mariadb + {{- end }} + livenessProbe: + exec: + command: ["/bin/ironic-liveness"] + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 10 + ports: + - containerPort: 6385 + name: api + protocol: TCP + readinessProbe: + exec: + command: ["/bin/ironic-readiness"] + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 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 + {{- 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 + {{- if .Values.persistence.ironic.size }} + persistentVolumeClaim: + claimName: ironic-shared-volume + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.global.enable_basicAuth }} + - name: ironic-basic-auth + secret: + secretName: ironic-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 + {{- 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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/issuers.yaml b/charts/metal3/0.9.1/charts/ironic/templates/issuers.yaml new file mode 100644 index 00000000..f97de264 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/issuers.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/pvc.yaml b/charts/metal3/0.9.1/charts/ironic/templates/pvc.yaml new file mode 100644 index 00000000..c757dd3f --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/pvc.yaml @@ -0,0 +1,26 @@ +{{- if .Values.persistence.ironic.size }} +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 +{{- end }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/secret-tls.yaml b/charts/metal3/0.9.1/charts/ironic/templates/secret-tls.yaml new file mode 100644 index 00000000..1f1611dd --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/secret-tls.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/secrets-basic-auth.yaml b/charts/metal3/0.9.1/charts/ironic/templates/secrets-basic-auth.yaml new file mode 100644 index 00000000..0ef47d37 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/secrets-basic-auth.yaml @@ -0,0 +1,33 @@ +{{- 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 }} + +{{- end }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/service.yaml b/charts/metal3/0.9.1/charts/ironic/templates/service.yaml new file mode 100644 index 00000000..c18fecbc --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/service.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/templates/serviceaccount.yaml b/charts/metal3/0.9.1/charts/ironic/templates/serviceaccount.yaml new file mode 100644 index 00000000..25fcc8d5 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/templates/serviceaccount.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/ironic/values.yaml b/charts/metal3/0.9.1/charts/ironic/values.yaml new file mode 100644 index 00000000..67aa59e7 --- /dev/null +++ b/charts/metal3/0.9.1/charts/ironic/values.yaml @@ -0,0 +1,150 @@ +# 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: 26.1.2.1 + ironicIPADownloader: + repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic-ipa-downloader + pullPolicy: IfNotPresent + tag: 3.0.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: 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: 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 e.g "1Gi" + # When unset persistent storage is disabled and emptyDir is enabled + size: "" + # 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 diff --git a/charts/metal3/0.9.1/charts/mariadb/.helmignore b/charts/metal3/0.9.1/charts/mariadb/.helmignore new file mode 100644 index 00000000..898df488 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/.helmignore @@ -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/ + diff --git a/charts/metal3/0.9.1/charts/mariadb/Chart.yaml b/charts/metal3/0.9.1/charts/mariadb/Chart.yaml new file mode 100644 index 00000000..caec5ee3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/Chart.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/_helpers.tpl b/charts/metal3/0.9.1/charts/mariadb/templates/_helpers.tpl new file mode 100644 index 00000000..bd963d0e --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/_helpers.tpl @@ -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 }} + diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/configmap.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/configmap.yaml new file mode 100644 index 00000000..ef498a98 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/configmap.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-cm + labels: + {{- include "mariadb.labels" . | nindent 4 }} +data: + RESTART_CONTAINER_CERTIFICATE_UPDATED: "false" diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/deployment.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/deployment.yaml new file mode 100644 index 00000000..9e30726a --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/deployment.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/pvc.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/pvc.yaml new file mode 100644 index 00000000..573e1525 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/pvc.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/secret.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/secret.yaml new file mode 100644 index 00000000..3cde9e58 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/secret.yaml @@ -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 }} \ No newline at end of file diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/service-account.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/service-account.yaml new file mode 100644 index 00000000..16794876 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/service-account.yaml @@ -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 }} + diff --git a/charts/metal3/0.9.1/charts/mariadb/templates/service.yaml b/charts/metal3/0.9.1/charts/mariadb/templates/service.yaml new file mode 100644 index 00000000..46b731fb --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/templates/service.yaml @@ -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 }} \ No newline at end of file diff --git a/charts/metal3/0.9.1/charts/mariadb/values.yaml b/charts/metal3/0.9.1/charts/mariadb/values.yaml new file mode 100644 index 00000000..23726d03 --- /dev/null +++ b/charts/metal3/0.9.1/charts/mariadb/values.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/media/.helmignore b/charts/metal3/0.9.1/charts/media/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/.helmignore @@ -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/ diff --git a/charts/metal3/0.9.1/charts/media/Chart.yaml b/charts/metal3/0.9.1/charts/media/Chart.yaml new file mode 100644 index 00000000..7b0b3d9b --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/Chart.yaml @@ -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.6.0 diff --git a/charts/metal3/0.9.1/charts/media/templates/NOTES.txt b/charts/metal3/0.9.1/charts/media/templates/NOTES.txt new file mode 100644 index 00000000..6823b8ca --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/NOTES.txt @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/_helpers.tpl b/charts/metal3/0.9.1/charts/media/templates/_helpers.tpl new file mode 100644 index 00000000..ae2a31da --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/_helpers.tpl @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/deployment.yaml b/charts/metal3/0.9.1/charts/media/templates/deployment.yaml new file mode 100644 index 00000000..e0e3fe81 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/deployment.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/hpa.yaml b/charts/metal3/0.9.1/charts/media/templates/hpa.yaml new file mode 100644 index 00000000..296a627b --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/hpa.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/ingress.yaml b/charts/metal3/0.9.1/charts/media/templates/ingress.yaml new file mode 100644 index 00000000..bc816995 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/ingress.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/persistentvolume.yaml b/charts/metal3/0.9.1/charts/media/templates/persistentvolume.yaml new file mode 100644 index 00000000..97e08f3f --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/persistentvolume.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/persistentvolumeclaim.yaml b/charts/metal3/0.9.1/charts/media/templates/persistentvolumeclaim.yaml new file mode 100644 index 00000000..d2c7e5d3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/persistentvolumeclaim.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/service.yaml b/charts/metal3/0.9.1/charts/media/templates/service.yaml new file mode 100644 index 00000000..5f199299 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/service.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/serviceaccount.yaml b/charts/metal3/0.9.1/charts/media/templates/serviceaccount.yaml new file mode 100644 index 00000000..513a44ab --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/serviceaccount.yaml @@ -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 }} diff --git a/charts/metal3/0.9.1/charts/media/templates/storageclass.yaml b/charts/metal3/0.9.1/charts/media/templates/storageclass.yaml new file mode 100644 index 00000000..001cdd9b --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/storageclass.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/media/templates/tests/test-connection.yaml b/charts/metal3/0.9.1/charts/media/templates/tests/test-connection.yaml new file mode 100644 index 00000000..aa4fe238 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/templates/tests/test-connection.yaml @@ -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 diff --git a/charts/metal3/0.9.1/charts/media/values.yaml b/charts/metal3/0.9.1/charts/media/values.yaml new file mode 100644 index 00000000..1d3a4da3 --- /dev/null +++ b/charts/metal3/0.9.1/charts/media/values.yaml @@ -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: 26.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 diff --git a/charts/metal3/0.9.1/templates/NOTES.txt b/charts/metal3/0.9.1/templates/NOTES.txt new file mode 100644 index 00000000..ecac059d --- /dev/null +++ b/charts/metal3/0.9.1/templates/NOTES.txt @@ -0,0 +1,3 @@ +TBD: Document the deployed application/service endpoints + +You should now be ready to install and configure ClusterAPI. diff --git a/charts/metal3/0.9.1/templates/_helpers.tpl b/charts/metal3/0.9.1/templates/_helpers.tpl new file mode 100644 index 00000000..17b1ac8c --- /dev/null +++ b/charts/metal3/0.9.1/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "metal3.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 "metal3.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 "metal3.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "metal3.labels" -}} +helm.sh/chart: {{ include "metal3.chart" . }} +{{ include "metal3.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "metal3.selectorLabels" -}} +app.kubernetes.io/name: {{ include "metal3.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "metal3.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "metal3.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/metal3/0.9.1/values.yaml b/charts/metal3/0.9.1/values.yaml new file mode 100644 index 00000000..f90afce2 --- /dev/null +++ b/charts/metal3/0.9.1/values.yaml @@ -0,0 +1,107 @@ +# The metal3 chart is a parent chart that installs +# all of the other charts that a metal3 deployment needs, +# but doesn't actually deploy any services itself. + +global: + # IP on which the Ironic services will be exposed + ironicIP: "" + + # whether to enable mariadb (default is sqlite) + enable_mariadb: false + + # whether to enable media server. + enable_metal3_media_server: false + + # 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 + + # whether to enable tls + enable_tls: true + + # whether to enable the TLS of the Virtual Media. + enable_vmedia_tls: true + + # whether to enable basic auth + enable_basicAuth: true + + auth: + ironicUsername: "" + ironicPassword: "" + + # whether to have additional trusted CA + # NOTE: If enabled, a secret with name tls-ca-additional should be deployed + # The secret should be like this: + # data: + # ca-additional.crt: + additionalTrustedCAs: false + + # Will be used when tls is enabled + vmediaTLSPort: 6185 + + # 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 range 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 + provisioningInterface: "" + + # IP Address assigned to network interface on provisioning network + provisioningIP: "" + + # Name for the MariaDB service + databaseServiceName: metal3-mariadb + + # In a multi-node cluster use the node selector to ensure the pods + # all run on the same host where the dnsmasqDNSServer and provisioningIP + # and /opt/media exist. Uncomment the nodeSelector and update the + # hostname accordingly. + #nodeSelector: + #kubernetes.io/hostname: "csrancher-n1" + +# +# media service +# + +# Override any settings for the metal3 media service here +metal3-media: + # location where media files should be placed so that they are + # available to the Ironic deployment services. + mediaVolume: + hostPath: /opt/media + + +# +# ironic service +# + +# Override any settings for the metal3 ironic service here +# Ensure the storageClass is defined +metal3-ironic: + service: + type: LoadBalancer + persistence: + ironic: + # storageClass for the ironic shared volume + storageClass: "" + +# +# Database Service +# + +# Override any settings for the metal3 mariadb service here +metal3-mariadb: + # storageClass for the mysql datastore + persistence: + storageClass: "" diff --git a/index.html b/index.html index 168bec72..35ebf8bc 100755 --- a/index.html +++ b/index.html @@ -267,14 +267,14 @@

Charts

- +
- Generated on: + Generated on: diff --git a/index.yaml b/index.yaml index cbb92103..479ab5fb 100755 --- a/index.yaml +++ b/index.yaml @@ -479,6 +479,36 @@ entries: - assets/kubevirt-dashboard-extension/kubevirt-dashboard-extension-0.1.0.tgz version: 0.1.0 metal3: + - apiVersion: v2 + appVersion: 1.16.0 + created: "2024-12-02T17:09:26.689+01:00" + dependencies: + - alias: metal3-baremetal-operator + name: baremetal-operator + repository: file://./charts/baremetal-operator + version: 0.6.0 + - alias: metal3-ironic + name: ironic + repository: file://./charts/ironic + version: 0.9.0 + - alias: metal3-mariadb + condition: global.enable_mariadb + name: mariadb + repository: file://./charts/mariadb + version: 0.5.4 + - alias: metal3-media + condition: global.enable_metal3_media_server + name: media + repository: file://./charts/media + version: 0.6.0 + description: A Helm chart that installs all of the dependencies needed for Metal3 + digest: 0fa58b8e14340c421f7dc931ff5dbb47dca55bba8a8e3c84f75aca5476a21bd5 + icon: https://github.com/cncf/artwork/raw/master/projects/metal3/icon/color/metal3-icon-color.svg + name: metal3 + type: application + urls: + - assets/metal3/metal3-0.9.1.tgz + version: 0.9.1 - apiVersion: v2 appVersion: 1.16.0 created: "2024-11-12T13:31:17.658733Z"