From 5ac5ad6dcce426c6b088280e1d19f08b0f97bf7c Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 11:00:02 +0400 Subject: [PATCH 01/17] qweqwe --- .gitignore | 1 + apps/templates/metal-lb.yaml | 16 + metal-lb/Chart.lock | 6 + metal-lb/Chart.yaml | 33 + metal-lb/README.md | 405 +++++++++ metal-lb/templates/NOTES.txt | 67 ++ metal-lb/templates/_helpers.tpl | 37 + metal-lb/templates/controller/configmap.yaml | 17 + metal-lb/templates/controller/deployment.yaml | 149 ++++ metal-lb/templates/controller/psp.yaml | 49 ++ metal-lb/templates/controller/rbac.yaml | 69 ++ metal-lb/templates/controller/service.yaml | 29 + .../templates/controller/serviceaccount.yaml | 22 + .../templates/controller/servicemonitor.yaml | 51 ++ metal-lb/templates/extra-list.yaml | 4 + metal-lb/templates/networkpolicy.yaml | 41 + .../templates/prometheus/metallb.alerts.yaml | 34 + metal-lb/templates/rbac.yaml | 49 ++ metal-lb/templates/speaker/daemonset.yaml | 165 ++++ metal-lb/templates/speaker/psp.yaml | 43 + metal-lb/templates/speaker/rbac.yaml | 105 +++ metal-lb/templates/speaker/secret.yaml | 20 + metal-lb/templates/speaker/service.yaml | 29 + .../templates/speaker/serviceaccount.yaml | 22 + .../templates/speaker/servicemonitor.yaml | 51 ++ metal-lb/values.yaml | 807 ++++++++++++++++++ 26 files changed, 2321 insertions(+) create mode 100644 .gitignore create mode 100644 apps/templates/metal-lb.yaml create mode 100644 metal-lb/Chart.lock create mode 100644 metal-lb/Chart.yaml create mode 100644 metal-lb/README.md create mode 100644 metal-lb/templates/NOTES.txt create mode 100644 metal-lb/templates/_helpers.tpl create mode 100644 metal-lb/templates/controller/configmap.yaml create mode 100644 metal-lb/templates/controller/deployment.yaml create mode 100644 metal-lb/templates/controller/psp.yaml create mode 100644 metal-lb/templates/controller/rbac.yaml create mode 100644 metal-lb/templates/controller/service.yaml create mode 100644 metal-lb/templates/controller/serviceaccount.yaml create mode 100644 metal-lb/templates/controller/servicemonitor.yaml create mode 100644 metal-lb/templates/extra-list.yaml create mode 100644 metal-lb/templates/networkpolicy.yaml create mode 100644 metal-lb/templates/prometheus/metallb.alerts.yaml create mode 100644 metal-lb/templates/rbac.yaml create mode 100644 metal-lb/templates/speaker/daemonset.yaml create mode 100644 metal-lb/templates/speaker/psp.yaml create mode 100644 metal-lb/templates/speaker/rbac.yaml create mode 100644 metal-lb/templates/speaker/secret.yaml create mode 100644 metal-lb/templates/speaker/service.yaml create mode 100644 metal-lb/templates/speaker/serviceaccount.yaml create mode 100644 metal-lb/templates/speaker/servicemonitor.yaml create mode 100644 metal-lb/values.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/apps/templates/metal-lb.yaml b/apps/templates/metal-lb.yaml new file mode 100644 index 0000000..bbdf4ae --- /dev/null +++ b/apps/templates/metal-lb.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: metal-lb + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: metal-lb + server: {{ .Values.spec.destination.server }} + project: default + source: + path: metal-lb + repoURL: {{ .Values.spec.source.repoURL }} + targetRevision: {{ .Values.spec.source.targetRevision }} diff --git a/metal-lb/Chart.lock b/metal-lb/Chart.lock new file mode 100644 index 0000000..1487dc7 --- /dev/null +++ b/metal-lb/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 1.16.0 +digest: sha256:f41cb9ff725b7c9fa2725634196a6813566d630342f86a74903ed114b282c8c0 +generated: "2022-06-06T11:37:37.250846899Z" diff --git a/metal-lb/Chart.yaml b/metal-lb/Chart.yaml new file mode 100644 index 0000000..e8aad69 --- /dev/null +++ b/metal-lb/Chart.yaml @@ -0,0 +1,33 @@ +annotations: + category: Infrastructure +apiVersion: v2 +appVersion: 0.12.1 +dependencies: + - name: common + repository: https://charts.bitnami.com/bitnami + tags: + - bitnami-common + version: 1.x.x +description: MetalLB is a load-balancer implementation for bare metal Kubernetes clusters, using standard routing protocols. +engine: gotpl +home: https://github.com/bitnami/charts/tree/master/bitnami/metallb +icon: https://bitnami.com/assets/stacks/metallb-speaker/img/metallb-speaker-stack-220x234.png +keywords: + - load-balancer + - balancer + - lb + - bgp + - arp + - vrrp + - vip +maintainers: + - name: cellebyte + email: cellebyte@gmail.com + - name: Bitnami + url: https://github.com/bitnami/charts +name: metallb +sources: + - https://github.com/metallb/metallb + - https://github.com/bitnami/bitnami-docker-metallb + - https://metallb.universe.tf +version: 3.0.9 diff --git a/metal-lb/README.md b/metal-lb/README.md new file mode 100644 index 0000000..7abc1eb --- /dev/null +++ b/metal-lb/README.md @@ -0,0 +1,405 @@ + + +# MetalLB packaged by Bitnami + +MetalLB is a load-balancer implementation for bare metal Kubernetes clusters, using standard routing protocols. + +[Overview of MetalLB](https://metallb.universe.tf/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +$ helm install my-release bitnami/metallb +``` + +## Introduction +Bitnami charts for Helm are carefully engineered, actively maintained and are the quickest and easiest way to deploy containers on a Kubernetes cluster that are ready to handle production workloads. + +This chart bootstraps a [MetalLB Controller](https://metallb.universe.tf/community/) Controller Deployment and a [MetalLB Speaker](https://metallb.universe.tf/community/) Daemonset on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- Virtual IPs for Layer 2 or Route Reflector for BGP setup. + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +$ helm install my-release bitnami/metallb +``` + +These commands deploy metallb on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` helm release: + +```console +$ helm uninstall my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ------------------------- | ----------------------------------------------- | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | + + +### Common parameters + +| Name | Description | Value | +| ------------------------ | --------------------------------------------------------------------------------------- | -------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override metallb.fullname include (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override metallb.fullname template | `""` | +| `commonLabels` | Add labels to all the deployed resources | `{}` | +| `commonAnnotations` | Add annotations to all the deployed resources | `{}` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the the deployment(s)/statefulset(s) | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the the deployment(s)/statefulset(s) | `["infinity"]` | + + +### MetalLB parameters + +| Name | Description | Value | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `existingConfigMap` | Specify the name of an externally-defined ConfigMap to use as the configuration. This is mutually exclusive with the `configInline` option. | `""` | +| `configInline` | Specifies MetalLB's configuration directly, in yaml format. | `{}` | +| `rbac.create` | Specifies whether to install and use RBAC rules | `true` | +| `psp.create` | Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later | `false` | +| `networkPolicy.enabled` | Enable NetworkPolicy | `false` | +| `networkPolicy.ingressNSMatchLabels` | Allow connections from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | For other namespaces match by pod labels and namespace labels | `{}` | +| `prometheusRule.enabled` | Prometheus Operator alertmanager alerts are created | `false` | + + +### Controller parameters + +| Name | Description | Value | +| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `controller.image.registry` | MetalLB Controller image registry | `docker.io` | +| `controller.image.repository` | MetalLB Controller image repository | `bitnami/metallb-controller` | +| `controller.image.tag` | MetalLB Controller image tag (immutable tags are recommended) | `0.12.1-debian-10-r59` | +| `controller.image.pullPolicy` | MetalLB Controller image pull policy | `IfNotPresent` | +| `controller.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `controller.updateStrategy.type` | Metallb controller deployment strategy type. | `RollingUpdate` | +| `controller.hostAliases` | Deployment pod host aliases | `[]` | +| `controller.rbac.create` | create specifies whether to install and use RBAC rules. | `true` | +| `controller.psp.create` | Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later | `true` | +| `controller.priorityClassName` | Metallb controller pods' priorityClassName | `""` | +| `controller.schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `controller.terminationGracePeriodSeconds` | In seconds, time the given to the Metallb controller pod needs to terminate gracefully | `0` | +| `controller.topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `controller.resources.limits` | The resources limits for the container | `{}` | +| `controller.resources.requests` | The requested resources for the container | `{}` | +| `controller.nodeSelector` | Node labels for controller pod assignment | `{}` | +| `controller.tolerations` | Tolerations for controller pod assignment | `[]` | +| `controller.affinity` | Affinity for controller pod assignment | `{}` | +| `controller.podAnnotations` | Controller Pod annotations | `{}` | +| `controller.podLabels` | Controller Pod labels | `{}` | +| `controller.podAffinityPreset` | Controller Pod affinitypreset. Allowed values: soft, hard | `""` | +| `controller.podAntiAffinityPreset` | Controller Pod anti affinitypreset. Allowed values: soft, hard | `soft` | +| `controller.nodeAffinityPreset.type` | Controller Pod Node affinity preset. Allowed values: soft, hard | `""` | +| `controller.nodeAffinityPreset.key` | Controller Pod Node affinity label key to match | `""` | +| `controller.nodeAffinityPreset.values` | Controller Pod Node affinity label values to match | `[]` | +| `controller.podSecurityContext.enabled` | Enabled Metallb Controller pods' Security Context | `true` | +| `controller.podSecurityContext.fsGroup` | Set Metallb Controller pod's Security Context fsGroup | `1001` | +| `controller.containerSecurityContext.enabled` | Enabled Metallb Controller containers' Security Context | `true` | +| `controller.containerSecurityContext.runAsUser` | Set Metallb Controller containers' Security Context runAsUser | `1001` | +| `controller.containerSecurityContext.runAsNonRoot` | Set Metallb Controller container's Security Context runAsNonRoot | `true` | +| `controller.containerSecurityContext.allowPrivilegeEscalation` | Enables privilege Escalation context for the pod. | `false` | +| `controller.containerSecurityContext.readOnlyRootFilesystem` | Allows the pod to mount the RootFS as ReadOnly | `true` | +| `controller.containerSecurityContext.capabilities.drop` | Drop capabilities for the securityContext | `[]` | +| `controller.command` | Override default container command (useful when using custom images) | `[]` | +| `controller.args` | Override default container args (useful when using custom images) | `[]` | +| `controller.lifecycleHooks` | for the Metallb Controller container(s) to automate configuration before or after startup | `{}` | +| `controller.extraEnvVars` | Extra environment variable to pass to the running container. | `[]` | +| `controller.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for Metallb controller nodes | `""` | +| `controller.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for Metallb controller nodes | `""` | +| `controller.extraVolumes` | Optionally specify extra list of additional volumes for the Metallb controller pod(s) | `[]` | +| `controller.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the Metallb controller container(s) | `[]` | +| `controller.sidecars` | Add additional sidecar containers to the Metallb Controller pod(s) | `[]` | +| `controller.initContainers` | Add additional init containers to the Metallb Controller pod(s) | `[]` | +| `controller.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `controller.serviceAccount.name` | Name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` | +| `controller.serviceAccount.automountServiceAccountToken` | Automount service account token for the server service account | `true` | +| `controller.serviceAccount.annotations` | Annotations for service account. Evaluated as a template. Only used if `create` is `true`. | `{}` | +| `controller.revisionHistoryLimit` | Configure the revisionHistoryLimit of the Controller deployment | `3` | +| `controller.containerPorts.metrics` | Configures the ports the MetalLB Controller listens on for metrics | `7472` | +| `controller.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `controller.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `10` | +| `controller.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `controller.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `controller.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `controller.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `controller.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `controller.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `10` | +| `controller.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `controller.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `controller.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `controller.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `controller.startupProbe.enabled` | Enable startupProbe | `false` | +| `controller.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `10` | +| `controller.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `controller.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `controller.startupProbe.failureThreshold` | Failure threshold for startupProbe | `3` | +| `controller.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `controller.customStartupProbe` | Custom liveness probe for the Web component | `{}` | +| `controller.customLivenessProbe` | Custom liveness probe for the Web component | `{}` | +| `controller.customReadinessProbe` | Custom readiness probe for the Web component | `{}` | + + +### Metallb controller Prometheus metrics export + +| Name | Description | Value | +| ----------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------ | +| `controller.metrics.enabled` | Enable the export of Prometheus metrics | `false` | +| `controller.metrics.service.port` | Prometheus metrics service port | `7472` | +| `controller.metrics.service.annotations` | Annotations for the Prometheus Exporter service service | `{}` | +| `controller.metrics.serviceMonitor.enabled` | Specify if a servicemonitor will be deployed for prometheus-operator | `false` | +| `controller.metrics.serviceMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `controller.metrics.serviceMonitor.jobLabel` | Specify the jobLabel to use for the prometheus-operator | `app.kubernetes.io/name` | +| `controller.metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `""` | +| `controller.metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `""` | +| `controller.metrics.serviceMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | +| `controller.metrics.serviceMonitor.relabelings` | Specify general relabeling | `[]` | +| `controller.metrics.serviceMonitor.selector` | ServiceMonitor selector labels | `{}` | +| `controller.metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `controller.metrics.serviceMonitor.honorLabels` | honorLabels chooses the metric's labels on collisions with target labels | `false` | + + +### Speaker parameters + +| Name | Description | Value | +| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `speaker.image.registry` | MetalLB Speaker image registry | `docker.io` | +| `speaker.image.repository` | MetalLB Speaker image repository | `bitnami/metallb-speaker` | +| `speaker.image.tag` | MetalLB Speaker image tag (immutable tags are recommended) | `0.12.1-debian-10-r59` | +| `speaker.image.pullPolicy` | MetalLB Speaker image pull policy | `IfNotPresent` | +| `speaker.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `speaker.updateStrategy.type` | Speaker daemonset strategy type | `RollingUpdate` | +| `speaker.rbac.create` | create specifies whether to install and use RBAC rules. | `true` | +| `speaker.hostAliases` | Deployment pod host aliases | `[]` | +| `speaker.psp.create` | Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later | `true` | +| `speaker.priorityClassName` | Speaker pods' priorityClassName | `""` | +| `speaker.terminationGracePeriodSeconds` | In seconds, time the given to the Speaker pod needs to terminate gracefully | `2` | +| `speaker.resources.limits` | The resources limits for the container | `{}` | +| `speaker.resources.requests` | The requested resources for the container | `{}` | +| `speaker.nodeSelector` | Node labels for speaker pod assignment | `{}` | +| `speaker.tolerations` | Tolerations for speaker pod assignment | `[]` | +| `speaker.affinity` | Affinity for speaker pod assignment | `{}` | +| `speaker.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `speaker.nodeAffinityPreset.key` | Node label key to match. Ignored if `speaker.affinity` is set | `""` | +| `speaker.nodeAffinityPreset.values` | Node label values to match. Ignored if `speaker.affinity` is set | `[]` | +| `speaker.podAffinityPreset` | Pod affinity preset. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `speaker.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `speaker.podAnnotations` | Speaker Pod annotations | `{}` | +| `speaker.podLabels` | Speaker Pod labels | `{}` | +| `speaker.podSecurityContext.enabled` | Enabled Speaker pods' Security Context | `true` | +| `speaker.podSecurityContext.fsGroup` | Set Speaker pod's Security Context fsGroup | `0` | +| `speaker.containerSecurityContext.enabled` | Enabled Speaker containers' Security Context | `true` | +| `speaker.containerSecurityContext.runAsUser` | Set Speaker containers' Security Context runAsUser | `0` | +| `speaker.containerSecurityContext.allowPrivilegeEscalation` | Enables privilege Escalation context for the pod. | `false` | +| `speaker.containerSecurityContext.readOnlyRootFilesystem` | Allows the pod to mount the RootFS as ReadOnly | `true` | +| `speaker.containerSecurityContext.capabilities.drop` | Drop capabilities for the securityContext | `[]` | +| `speaker.containerSecurityContext.capabilities.add` | Add capabilities for the securityContext | `[]` | +| `speaker.command` | Override default container command (useful when using custom images) | `[]` | +| `speaker.args` | Override default container args (useful when using custom images) | `[]` | +| `speaker.lifecycleHooks` | for the Speaker container(s) to automate configuration before or after startup | `{}` | +| `speaker.sidecars` | Add additional sidecar containers to the Speaker pod(s) | `[]` | +| `speaker.initContainers` | Add additional init containers to the Speaker pod(s) | `[]` | +| `speaker.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `speaker.serviceAccount.name` | Name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` | +| `speaker.serviceAccount.automountServiceAccountToken` | Automount service account token for the server service account | `true` | +| `speaker.serviceAccount.annotations` | Annotations for service account. Evaluated as a template. Only used if `create` is `true`. | `{}` | +| `speaker.secretName` | References a Secret name for the member secret outside of the helm chart | `""` | +| `speaker.secretKey` | References a Secret key the member secret outside of the helm chart | `""` | +| `speaker.secretValue` | Custom value for `speaker.secretKey` | `""` | +| `speaker.extraEnvVars` | Extra environment variable to pass to the running container. | `[]` | +| `speaker.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for Speaker nodes | `""` | +| `speaker.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for Speaker nodes | `""` | +| `speaker.extraVolumes` | Optionally specify extra list of additional volumes for the Speaker pod(s) | `[]` | +| `speaker.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the Speaker container(s) | `[]` | +| `speaker.containerPorts.metrics` | HTTP Metrics Endpoint | `7472` | +| `speaker.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `speaker.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `10` | +| `speaker.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `speaker.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `speaker.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `speaker.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `speaker.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `speaker.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `10` | +| `speaker.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `speaker.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `speaker.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `speaker.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `speaker.startupProbe.enabled` | Enable startupProbe | `false` | +| `speaker.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `10` | +| `speaker.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `speaker.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `speaker.startupProbe.failureThreshold` | Failure threshold for startupProbe | `3` | +| `speaker.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `speaker.customStartupProbe` | Custom liveness probe for the Web component | `{}` | +| `speaker.customLivenessProbe` | Custom liveness probe for the Web component | `{}` | +| `speaker.customReadinessProbe` | Custom readiness probe for the Web component | `{}` | + + +### Speaker Prometheus metrics export + +| Name | Description | Value | +| -------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------ | +| `speaker.metrics.enabled` | Enable the export of Prometheus metrics | `false` | +| `speaker.metrics.service.port` | Prometheus metrics service port | `7472` | +| `speaker.metrics.service.annotations` | Annotations for the Prometheus Exporter service service | `{}` | +| `speaker.metrics.serviceMonitor.enabled` | Enable support for Prometheus Operator | `false` | +| `speaker.metrics.serviceMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `speaker.metrics.serviceMonitor.jobLabel` | Job label for scrape target | `app.kubernetes.io/name` | +| `speaker.metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `""` | +| `speaker.metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `""` | +| `speaker.metrics.serviceMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | +| `speaker.metrics.serviceMonitor.relabelings` | Specify general relabeling | `[]` | +| `speaker.metrics.serviceMonitor.selector` | ServiceMonitor selector labels | `{}` | +| `speaker.metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `speaker.metrics.serviceMonitor.honorLabels` | honorLabels chooses the metric's labels on collisions with target labels | `false` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install my-release \ + --set readinessProbe.successThreshold=5 \ + bitnami/metallb +``` +The above command sets the `readinessProbe.successThreshold` to `5`. + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +To configure [MetalLB](https://metallb.universe.tf) please look into the configuration section [MetalLB Configuration](https://metallb.universe.tf/configuration/). + +### Example Layer 2 configuration + +```yaml +configInline: + # The address-pools section lists the IP addresses that MetalLB is + # allowed to allocate, along with settings for how to advertise + # those addresses over BGP once assigned. You can have as many + # address pools as you want. + address-pools: + - # A name for the address pool. Services can request allocation + # from a specific address pool using this name, by listing this + # name under the 'metallb.universe.tf/address-pool' annotation. + name: generic-cluster-pool + # Protocol can be used to select how the announcement is done. + # Supported values are bgp and layer2. + protocol: layer2 + # A list of IP address ranges over which MetalLB has + # authority. You can list multiple ranges in a single pool, they + # will all share the same settings. Each range can be either a + # CIDR prefix, or an explicit start-end range of IPs. + addresses: + - 10.27.50.30-10.27.50.35 +``` + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 3.0.0 + +This major release renames several values in this chart and adds missing features, in order to be aligned with the rest of the assets in the Bitnami charts repository. + +Affected values: + +- `.prometheus` has been renamed as `.metrics`. +- To enable the Prometheus serviceMonitors, it is necessary to enable both `.metrics.enabled` and `.metrics.serviceMonitor.enabled`. +- Added the values section `.metrics.service`. +- `.securityContext` has been split as `.podSecurityContext` and `.containerSecurityContext` +- `controller.containerPort` has been renamed as `controller.containerPorts`. +- `speaker.daemonset.hostPorts.metrics` renamed as `speaker.containerPorts.metrics` +- `speaker.daemonset.terminationGracePeriodSeconds` renamed as speaker.terminationGracePeriodSeconds + +### To 2.0.0 + +**What changes were introduced in this major version?** + +- The `.Values.prometheus` section was moved into the components `.Values.controller.prometheus` and `.Values.speaker.prometheus` +- The `prometheus.prometheusRule` which is used to toggle the deployment of the metallb alerts is moved under the root of the `.Values.prometheusRule` +- A globel `.Values.psp.create` and `.Values.rbac.create` was introduced together with the option of toggeling for each component. (global option overwrites component options) + - `Values.controller.rbac.create` and `Values.controller.psp.create` + - `Values.speaker.rbac.create` and `Values.speaker.psp.create` + +**Considerations when upgrading to this version** + +- Check if you used the `prometheus` section in you deployment. +- If you do so, place the configuration you made into the sections `controller.prometheus` and `speaker.prometheus`. +- `prometheusRule` should stay under the root of your values. + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +**What changes were introduced in this major version?** + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +**Considerations when upgrading to this version** + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +**Useful links** + +- https://docs.bitnami.com/tutorials/resolve-helm2-helm3-post-migration-issues/ +- https://helm.sh/docs/topics/v2_v3_migration/ +- https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/ + +## Community supported solution + +Please, note this Helm chart is a community-supported solution. This means that the Bitnami team is not actively working on new features/improvements nor providing support through GitHub Issues for this Helm chart. Any new issue will stay open for 20 days to allow the community to contribute, after 15 days without activity the issue will be marked as stale being closed after 5 days. + +The Bitnami team will review any PR that is created, feel free to create a PR if you find any issue or want to implement a new feature. + +New versions are not going to be affected. Once a new version is released in the upstream project, the Bitnami container image will be updated to use the latest version. + +## License + +Copyright © 2022 Bitnami + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/metal-lb/templates/NOTES.txt b/metal-lb/templates/NOTES.txt new file mode 100644 index 0000000..ccafb57 --- /dev/null +++ b/metal-lb/templates/NOTES.txt @@ -0,0 +1,67 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ include "common.names.namespace" . }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ include "common.names.namespace" . }} -ti -- bash + +In order to replicate the container startup scripts execute these commands in their respective pods: + + speaker --port={{ .Values.speaker.containerPorts.metrics }} --config={{ include "metallb.configMapName" . }} + controller --port={{ .Values.controller.containerPorts.metrics }} --config={{ include "metallb.configMapName" . }} + +{{- else }} + +MetalLB is now running in the cluster + +LoadBalancer Services in your cluster are now available on the IPs you +defined in MetalLB's configuration. To see IP assignments, + + kubectl get services -o wide --all-namespaces | grep --color=never -E 'LoadBalancer|NAMESPACE' + +should be executed. + +To see the currently configured configuration for metallb run + + kubectl get configmaps --namespace {{ include "common.names.namespace" . }} {{ include "metallb.configMapName" . }} -o yaml + +in your preferred shell. + +{{- if .Values.existingConfigMap }} +WARNING: you specified a ConfigMap that isn't managed by +Helm. LoadBalancer services will not function until you add that +ConfigMap to your cluster yourself. + +Ensure you put the configmap in place + + kubectl get configmaps --namespace {{ include "common.names.namespace" . }} | grep --color=never -E "{{ include "metallb.configMapName" . }}|NAME" + +If it is missing create it with: + + kubectl create configmap {{ include "metallb.configMapName" . }} --namespace {{ include "common.names.namespace" . }} --from-file=config +{{- end }} + +{{- if .Values.speaker.secretName }} +WARNING: you specified a secretName that isn't managed by +Helm. The MetalLB speakers will not join without the secret in place. + + kubectl get secrets --namespace {{ include "common.names.namespace" . }} | grep --color=never -E "{{ include "metallb.speaker.secretName" . }}|NAME" + +If it is missing create it with: + + kubectl create secret {{ include "metallb.speaker.secretName" . }} --from-file={{ include "metallb.speaker.secretKey" . }} +{{- end }} +{{- end }} diff --git a/metal-lb/templates/_helpers.tpl b/metal-lb/templates/_helpers.tpl new file mode 100644 index 0000000..19b4205 --- /dev/null +++ b/metal-lb/templates/_helpers.tpl @@ -0,0 +1,37 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "metallb.controller.serviceAccountName" -}} +{{ include "common.secrets.name" (dict "existingSecret" .Values.controller.serviceAccount.name "defaultNameSuffix" "controller" "context" $) }} +{{- end -}} + +{{/* +Create the name of the speaker service account to use +*/}} +{{- define "metallb.speaker.serviceAccountName" -}} +{{ include "common.secrets.name" (dict "existingSecret" .Values.speaker.serviceAccount.name "defaultNameSuffix" "speaker" "context" $) }} +{{- end -}} + +{{/* +Create the name of the settings ConfigMap to use. +*/}} +{{- define "metallb.configMapName" -}} +{{ include "common.secrets.name" (dict "existingSecret" .Values.existingConfigMap "defaultNameSuffix" "config" "context" $) }} +{{- end -}} + +{{/* +Create the name of the member Secret to use. +*/}} +{{- define "metallb.speaker.secretName" -}} +{{ include "common.secrets.name" (dict "existingSecret" .Values.speaker.secretName "defaultNameSuffix" "memberlist" "context" $) }} +{{- end -}} + +{{/* +Create the key of the member Secret to use. +*/}} +{{- define "metallb.speaker.secretKey" -}} +{{ include "common.secrets.key" (dict "existingSecret" .Values.speaker.secretKey "key" "secretkey") }} +{{- end -}} + diff --git a/metal-lb/templates/controller/configmap.yaml b/metal-lb/templates/controller/configmap.yaml new file mode 100644 index 0000000..7bafe90 --- /dev/null +++ b/metal-lb/templates/controller/configmap.yaml @@ -0,0 +1,17 @@ +{{- if not .Values.existingConfigMap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "metallb.configMapName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + config: | +{{ include "common.tplvalues.render" ( dict "value" .Values.configInline "context" $) | indent 4 }} +{{- end -}} diff --git a/metal-lb/templates/controller/deployment.yaml b/metal-lb/templates/controller/deployment.yaml new file mode 100644 index 0000000..714d4ee --- /dev/null +++ b/metal-lb/templates/controller/deployment.yaml @@ -0,0 +1,149 @@ +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: 1 + {{- if .Values.controller.updateStrategy }} + strategy: {{- toYaml .Values.controller.updateStrategy | nindent 4 }} + {{- end }} + revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + template: + metadata: + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.controller.podLabels "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.podAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.controller.podAnnotations "context" $) | nindent 8 }} + {{- end }} + spec: + {{- include "common.images.pullSecrets" (dict "images" (list .Values.speaker.image .Values.controller.image) "global" .Values.global) | nindent 6 }} + {{- if .Values.controller.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.controller.hostAliases "context" $) | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "metallb.controller.serviceAccountName" . }} + nodeSelector: + "kubernetes.io/os": linux + {{- if .Values.controller.nodeSelector }} + {{- include "common.tplvalues.render" (dict "value" .Values.controller.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.controller.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.controller.podAffinityPreset "component" "controller" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.controller.podAntiAffinityPreset "component" "controller" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.controller.nodeAffinityPreset.type "key" .Values.controller.nodeAffinityPreset.key "values" .Values.controller.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.controller.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName | quote }} + {{- end }} + {{- if .Values.controller.schedulerName }} + schedulerName: {{ .Values.controller.schedulerName | quote }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.controller.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.podSecurityContext.enabled }} + securityContext: {{- omit .Values.controller.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.controller.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.controller.initContainers }} + initContainers: {{- include "common.tplvalues.render" (dict "value" .Values.controller.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: metallb-controller + image: {{ include "common.images.image" (dict "imageRoot" .Values.controller.image "global" .Values.global) }} + imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + {{- if .Values.controller.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.controller.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.controller.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.controller.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.controller.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.controller.args "context" $) | nindent 12 }} + {{- else }} + args: + - --port={{ .Values.controller.containerPorts.metrics }} + - --config={{ include "metallb.configMapName" . }} + {{- end }} + {{- if .Values.controller.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.controller.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + {{- if .Values.controller.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.controller.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.controller.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.controller.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.controller.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.controller.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.controller.containerPorts.metrics }} + {{- if .Values.controller.extraVolumeMounts }} + volumeMounts: {{- include "common.tplvalues.render" (dict "value" .Values.controller.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.controller.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.controller.livenessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- else if .Values.controller.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.controller.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.controller.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.controller.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- else if .Values.controller.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.controller.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.controller.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.controller.startupProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: metrics + {{- else if .Values.controller.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.controller.customStartupProbe "context" $) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.controller.resources }} + resources: {{- toYaml .Values.controller.resources | nindent 12 }} + {{- end }} + {{- if .Values.controller.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.controller.sidecars "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.extraVolumes }} + volumes: {{- include "common.tplvalues.render" (dict "value" .Values.controller.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/metal-lb/templates/controller/psp.yaml b/metal-lb/templates/controller/psp.yaml new file mode 100644 index 0000000..7ae4238 --- /dev/null +++ b/metal-lb/templates/controller/psp.yaml @@ -0,0 +1,49 @@ +{{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- if and $pspAvailable .Values.psp.create .Values.controller.psp.create -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: {{ .Values.controller.containerSecurityContext.allowPrivilegeEscalation }} + allowedCapabilities: [] + allowedHostPaths: [] + defaultAddCapabilities: [] + defaultAllowPrivilegeEscalation: {{ .Values.controller.containerSecurityContext.allowPrivilegeEscalation }} + fsGroup: + ranges: + - max: {{ .Values.controller.podSecurityContext.fsGroup }} + min: {{ .Values.controller.podSecurityContext.fsGroup }} + rule: MustRunAs + hostIPC: false + hostNetwork: false + hostPID: false + privileged: false + readOnlyRootFilesystem: {{ .Values.controller.containerSecurityContext.readOnlyRootFilesystem }} + requiredDropCapabilities: {{- toYaml .Values.controller.containerSecurityContext.capabilities.drop | nindent 2 }} + runAsUser: + ranges: + - max: {{ .Values.controller.containerSecurityContext.runAsUser }} + min: {{ .Values.controller.containerSecurityContext.runAsUser }} + rule: MustRunAs + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: {{ .Values.controller.containerSecurityContext.runAsUser }} + min: {{ .Values.controller.containerSecurityContext.runAsUser }} + rule: MustRunAs + volumes: + - configMap + - secret + - emptyDir +{{- end -}} diff --git a/metal-lb/templates/controller/rbac.yaml b/metal-lb/templates/controller/rbac.yaml new file mode 100644 index 0000000..53cdfd7 --- /dev/null +++ b/metal-lb/templates/controller/rbac.yaml @@ -0,0 +1,69 @@ +{{- if and .Values.rbac.create .Values.controller.rbac.create -}} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRole +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - '' + resources: + - services + verbs: + - get + - list + - watch + - update + - apiGroups: + - '' + resources: + - services/status + verbs: + - update + - apiGroups: + - '' + resources: + - events + verbs: + - create + - patch + - apiGroups: + - policy + resourceNames: + - {{ printf "%s-controller" (include "common.names.fullname" .) }} + resources: + - podsecuritypolicies + verbs: + - use +--- +## Role bindings +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "metallb.controller.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} +{{- end -}} diff --git a/metal-lb/templates/controller/service.yaml b/metal-lb/templates/controller/service.yaml new file mode 100644 index 0000000..6df24bf --- /dev/null +++ b/metal-lb/templates/controller/service.yaml @@ -0,0 +1,29 @@ +{{- if .Values.controller.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-controller-metrics" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.controller.metrics.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.controller.metrics.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + clusterIP: "None" + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: controller + ports: + - name: metrics + port: {{ .Values.controller.metrics.service.port }} + protocol: TCP + targetPort: {{ .Values.controller.containerPorts.metrics }} +{{- end }} diff --git a/metal-lb/templates/controller/serviceaccount.yaml b/metal-lb/templates/controller/serviceaccount.yaml new file mode 100644 index 0000000..70b3464 --- /dev/null +++ b/metal-lb/templates/controller/serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.controller.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "metallb.controller.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.controller.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.controller.serviceAccount.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.controller.serviceAccount.annotations "context" $) | nindent 4 }} + {{- end }} + {{- end }} +automountServiceAccountToken: {{ .Values.controller.serviceAccount.automountServiceAccountToken }} +{{- end -}} diff --git a/metal-lb/templates/controller/servicemonitor.yaml b/metal-lb/templates/controller/servicemonitor.yaml new file mode 100644 index 0000000..2ad796a --- /dev/null +++ b/metal-lb/templates/controller/servicemonitor.yaml @@ -0,0 +1,51 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + {{- if .Values.controller.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.controller.metrics.serviceMonitor.namespace | quote }} + {{- else }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- end }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.controller.metrics.serviceMonitor.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.controller.metrics.serviceMonitor.jobLabel | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.controller.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" .| quote }} + endpoints: + - port: metrics + {{- if .Values.controller.metrics.serviceMonitor.interval }} + interval: {{ .Values.controller.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.controller.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.controller.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.controller.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.controller.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/metal-lb/templates/extra-list.yaml b/metal-lb/templates/extra-list.yaml new file mode 100644 index 0000000..9ac65f9 --- /dev/null +++ b/metal-lb/templates/extra-list.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/metal-lb/templates/networkpolicy.yaml b/metal-lb/templates/networkpolicy.yaml new file mode 100644 index 0000000..2563f84 --- /dev/null +++ b/metal-lb/templates/networkpolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ printf "%s-controller" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + policyTypes: + - Ingress + ingress: + # Allow prometheus scrapes for metrics + - ports: + - port: {{ .Values.controller.containerPorts.metrics }} + protocol: TCP + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + from: + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/metal-lb/templates/prometheus/metallb.alerts.yaml b/metal-lb/templates/prometheus/metallb.alerts.yaml new file mode 100644 index 0000000..eb14689 --- /dev/null +++ b/metal-lb/templates/prometheus/metallb.alerts.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.prometheusRule.enabled .Values.speaker.metrics.serviceMonitor.enabled .Values.controller.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }}.alerts + rules: + - alert: MetalLBStaleConfig + annotations: + message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container_name }} on {{ $labels.instance + }} has a stale config for > 1 minute'`}} + expr: metallb_k8s_client_config_stale_bool{job="{{ include "common.names.name" . }}"} == 1 + for: 1m + labels: + severity: warning + - alert: MetalLBConfigNotLoaded + annotations: + message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container_name }} on {{ $labels.instance + }} has not loaded for > 1 minute'`}} + expr: metallb_k8s_client_config_loaded_bool{job="{{ include "common.names.name" . }}"} == 0 + for: 1m + labels: + severity: warning +{{- end }} diff --git a/metal-lb/templates/rbac.yaml b/metal-lb/templates/rbac.yaml new file mode 100644 index 0000000..7f1cc10 --- /dev/null +++ b/metal-lb/templates/rbac.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.rbac.create (or .Values.controller.rbac.create .Values.speaker.rbac.create ) -}} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ printf "%s-config-watcher" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - '' + resources: + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ printf "%s-config-watcher" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +subjects: +{{- if .Values.controller.rbac.create }} + - kind: ServiceAccount + name: {{ include "metallb.controller.serviceAccountName" . }} +{{- end }} +{{- if .Values.speaker.rbac.create }} + - kind: ServiceAccount + name: {{ include "metallb.speaker.serviceAccountName" . }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ printf "%s-config-watcher" (include "common.names.fullname" .) }} +{{- end -}} diff --git a/metal-lb/templates/speaker/daemonset.yaml b/metal-lb/templates/speaker/daemonset.yaml new file mode 100644 index 0000000..3c069af --- /dev/null +++ b/metal-lb/templates/speaker/daemonset.yaml @@ -0,0 +1,165 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.speaker.updateStrategy }} + updateStrategy: {{- toYaml .Values.speaker.updateStrategy | nindent 4 }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: speaker + template: + metadata: + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: speaker + {{- if .Values.speaker.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.speaker.podLabels "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.speaker.podAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.podAnnotations "context" $) | nindent 8 }} + {{- end }} + spec: + {{- include "common.images.pullSecrets" (dict "images" (list .Values.speaker.image .Values.controller.image) "global" .Values.global) | nindent 6 }} + {{- if .Values.speaker.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.hostAliases "context" $) | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "metallb.speaker.serviceAccountName" . }} + {{- if .Values.speaker.affinity }} + affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.speaker.podAffinityPreset "component" "speaker" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.speaker.podAntiAffinityPreset "component" "speaker" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.speaker.nodeAffinityPreset.type "key" .Values.speaker.nodeAffinityPreset.key "values" .Values.speaker.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + nodeSelector: + {{- if .Values.speaker.nodeSelector }} + {{- include "common.tplvalues.render" (dict "value" .Values.speaker.nodeSelector "context" $) | nindent 8 }} + {{- end }} + "kubernetes.io/os": linux + {{- if .Values.speaker.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.tolerations "context" $) | nindent 8 }} + {{- end }} + hostNetwork: true + {{- if .Values.speaker.priorityClassName }} + priorityClassName: {{ .Values.speaker.priorityClassName | quote }} + {{- end }} + {{- if .Values.speaker.podSecurityContext.enabled }} + securityContext: {{- omit .Values.speaker.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.speaker.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.speaker.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.speaker.initContainers }} + initContainers: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: metallb-speaker + image: {{ include "common.images.image" (dict "imageRoot" .Values.speaker.image "global" .Values.global) }} + imagePullPolicy: {{ .Values.speaker.image.pullPolicy }} + {{- if .Values.speaker.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.speaker.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.speaker.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.speaker.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.args "context" $) | nindent 12 }} + {{- else }} + args: + - --port={{ .Values.speaker.containerPorts.metrics }} + - --config={{ include "metallb.configMapName" . }} + {{- end }} + {{- if .Values.speaker.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: METALLB_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: METALLB_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: METALLB_ML_BIND_ADDR + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: METALLB_ML_LABELS + value: "app.kubernetes.io/name={{ include "common.names.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=speaker" + - name: METALLB_ML_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: METALLB_ML_SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ include "metallb.speaker.secretName" . }} + key: {{ include "metallb.speaker.secretKey" . }} + {{- if .Values.speaker.extraEnvVars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.extraEnvVars "context" $ ) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.speaker.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.speaker.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.speaker.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.speaker.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.speaker.containerPorts.metrics }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.speaker.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.speaker.livenessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- else if .Values.speaker.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.speaker.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.speaker.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- else if .Values.speaker.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.speaker.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.speaker.startupProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: metrics + {{- else if .Values.speaker.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.customStartupProbe "context" $) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.speaker.resources }} + resources: {{- toYaml .Values.speaker.resources | nindent 12 }} + {{- end }} + {{- if .Values.speaker.extraVolumeMounts }} + volumeMounts: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.speaker.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.sidecars "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.speaker.extraVolumes }} + volumes: {{- include "common.tplvalues.render" (dict "value" .Values.speaker.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/metal-lb/templates/speaker/psp.yaml b/metal-lb/templates/speaker/psp.yaml new file mode 100644 index 0000000..dc588bd --- /dev/null +++ b/metal-lb/templates/speaker/psp.yaml @@ -0,0 +1,43 @@ +{{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- if and $pspAvailable .Values.psp.create .Values.speaker.psp.create -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: {{ .Values.speaker.containerSecurityContext.allowPrivilegeEscalation }} + allowedCapabilities: {{- toYaml .Values.speaker.containerSecurityContext.capabilities.add | nindent 2 }} + allowedHostPaths: [] + defaultAddCapabilities: {{- toYaml .Values.speaker.containerSecurityContext.capabilities.add | nindent 2 }} + defaultAllowPrivilegeEscalation: {{ .Values.speaker.containerSecurityContext.allowPrivilegeEscalation }} + fsGroup: + rule: RunAsAny + hostIPC: false + hostNetwork: true + hostPID: false + hostPorts: + - max: {{ .Values.speaker.containerPorts.metrics }} + min: {{ .Values.speaker.containerPorts.metrics }} + privileged: true + readOnlyRootFilesystem: {{ .Values.speaker.containerSecurityContext.readOnlyRootFilesystem }} + requiredDropCapabilities: {{- toYaml .Values.speaker.containerSecurityContext.capabilities.drop | nindent 2 }} + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - configMap + - secret + - emptyDir +{{- end -}} diff --git a/metal-lb/templates/speaker/rbac.yaml b/metal-lb/templates/speaker/rbac.yaml new file mode 100644 index 0000000..ba05e75 --- /dev/null +++ b/metal-lb/templates/speaker/rbac.yaml @@ -0,0 +1,105 @@ +{{- if and .Values.rbac.create .Values.speaker.rbac.create -}} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRole +metadata: + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - '' + resources: + - services + - endpoints + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - '' + resources: + - events + verbs: + - create + - patch + - apiGroups: + - policy + resourceNames: + - {{ printf "%s-speaker" (include "common.names.fullname" .) }} + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ printf "%s-pod-lister" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - '' + resources: + - pods + verbs: + - list +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "metallb.speaker.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ printf "%s-pod-lister" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ printf "%s-pod-lister" (include "common.names.fullname" .) }} +subjects: + - kind: ServiceAccount + name: {{ include "metallb.speaker.serviceAccountName" . }} +{{- end -}} diff --git a/metal-lb/templates/speaker/secret.yaml b/metal-lb/templates/speaker/secret.yaml new file mode 100644 index 0000000..3844334 --- /dev/null +++ b/metal-lb/templates/speaker/secret.yaml @@ -0,0 +1,20 @@ +{{- if not .Values.speaker.secretName }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "metallb.speaker.secretName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + {{ include "metallb.speaker.secretKey" . }}: {{ include "common.secrets.passwords.manage" (dict "secret" ( include "metallb.speaker.secretName" .) "key" ( include "metallb.speaker.secretKey" .) "providedValues" (list "speaker.secretValue") "length" 256 "context" $) }} +{{- end }} diff --git a/metal-lb/templates/speaker/service.yaml b/metal-lb/templates/speaker/service.yaml new file mode 100644 index 0000000..31c7e83 --- /dev/null +++ b/metal-lb/templates/speaker/service.yaml @@ -0,0 +1,29 @@ +{{- if .Values.speaker.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-speaker-metrics" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.speaker.metrics.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.metrics.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + clusterIP: "None" + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: speaker + ports: + - name: metrics + port: {{ .Values.speaker.metrics.service.port }} + protocol: TCP + targetPort: {{ .Values.speaker.containerPorts.metrics }} +{{- end }} diff --git a/metal-lb/templates/speaker/serviceaccount.yaml b/metal-lb/templates/speaker/serviceaccount.yaml new file mode 100644 index 0000000..abc4b31 --- /dev/null +++ b/metal-lb/templates/speaker/serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.speaker.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "metallb.speaker.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.speaker.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.speaker.serviceAccount.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.speaker.serviceAccount.annotations "context" $) | nindent 4 }} + {{- end }} + {{- end }} +automountServiceAccountToken: {{ .Values.speaker.serviceAccount.automountServiceAccountToken }} +{{- end -}} diff --git a/metal-lb/templates/speaker/servicemonitor.yaml b/metal-lb/templates/speaker/servicemonitor.yaml new file mode 100644 index 0000000..5d2cde7 --- /dev/null +++ b/metal-lb/templates/speaker/servicemonitor.yaml @@ -0,0 +1,51 @@ +{{- if and .Values.speaker.metrics.enabled .Values.speaker.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ printf "%s-speaker" (include "common.names.fullname" .) }} + {{- if .Values.speaker.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.speaker.metrics.serviceMonitor.namespace | quote }} + {{- else }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- end }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: speaker + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.speaker.metrics.serviceMonitor.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.metrics.serviceMonitor.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.speaker.metrics.serviceMonitor.jobLabel | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: speaker + {{- if .Values.speaker.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.speaker.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" .| quote }} + endpoints: + - port: metrics + {{- if .Values.speaker.metrics.serviceMonitor.interval }} + interval: {{ .Values.speaker.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.speaker.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.speaker.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.speaker.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.speaker.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.speaker.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.speaker.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.speaker.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/metal-lb/values.yaml b/metal-lb/values.yaml new file mode 100644 index 0000000..b0eaa06 --- /dev/null +++ b/metal-lb/values.yaml @@ -0,0 +1,807 @@ +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + +## @section Common parameters + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override metallb.fullname include (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override metallb.fullname template +## +fullnameOverride: "" +## @param commonLabels Add labels to all the deployed resources +## +commonLabels: {} +## @param commonAnnotations Add annotations to all the deployed resources +## +commonAnnotations: {} +## @param extraDeploy Array of extra objects to deploy with the release +## +extraDeploy: [] + +## Enable diagnostic mode in the deployment(s)/statefulset(s) +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the the deployment(s)/statefulset(s) + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the the deployment(s)/statefulset(s) + ## + args: + - infinity +## @section MetalLB parameters + +## To configure MetalLB, you must specify ONE of the following two +## options. +## @param existingConfigMap Specify the name of an externally-defined ConfigMap to use as the configuration. This is mutually exclusive with the `configInline` option. +## Helm will not manage the contents of this ConfigMap, it is your responsibility to create it. +## e.g: +## existingConfigMap: metallb-config +## +existingConfigMap: "" +## @param configInline Specifies MetalLB's configuration directly, in yaml format. +## When configInline is used, Helm manages MetalLB's +## configuration ConfigMap as part of the release, and +## existingConfigMap is ignored. +## Refer to https://metallb.universe.tf/configuration/ for +## available options. +## +configInline: {} +## RBAC creation for controller and speaker +## +rbac: + ## @param rbac.create Specifies whether to install and use RBAC rules + ## + create: true +## PSP creation for controller and speaker +## +psp: + ## @param psp.create Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later + ## + create: false +## Prometheus Operator alertmanager alerts +## +networkPolicy: + ## @param networkPolicy.enabled Enable NetworkPolicy + ## Prometheus scraping of the controller + ## + enabled: false + ## @param networkPolicy.ingressNSMatchLabels Allow connections from other namespaces + ## Set label for namespace and pods (optional). + ## + ingressNSMatchLabels: {} + ## @param networkPolicy.ingressNSPodMatchLabels For other namespaces match by pod labels and namespace labels + ## + ingressNSPodMatchLabels: {} +## @param prometheusRule.enabled Prometheus Operator alertmanager alerts are created +## +prometheusRule: + enabled: false + +## @section Controller parameters + +## Metallb Controller deployment. +## ref: https://hub.docker.com/r/bitnami/metallb-controller/tags +## +controller: + ## @param controller.image.registry MetalLB Controller image registry + ## @param controller.image.repository MetalLB Controller image repository + ## @param controller.image.tag MetalLB Controller image tag (immutable tags are recommended) + ## @param controller.image.pullPolicy MetalLB Controller image pull policy + ## @param controller.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/metallb-controller + tag: 0.12.1-debian-11-r3 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param controller.updateStrategy.type Metallb controller deployment strategy type. + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + ## e.g: + ## updateStrategy: + ## type: RollingUpdate + ## rollingUpdate: + ## maxSurge: 25% + ## maxUnavailable: 25% + ## + updateStrategy: + type: RollingUpdate + ## @param controller.hostAliases Deployment pod host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## If global .Values.rbac.create is disabled no rbac is created. + ## This value is then meaningless + ## Defines if the controller rbac should be created. + ## + rbac: + ## @param controller.rbac.create create specifies whether to install and use RBAC rules. + ## + create: true + ## If global .Values.psp.create is disabled no psp is created. + ## This value is then meaningless + ## Defines if the controller psp should be created. + ## + psp: + ## @param controller.psp.create Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later + ## + create: true + ## @param controller.priorityClassName Metallb controller pods' priorityClassName + ## + priorityClassName: "" + ## @param controller.schedulerName Name of the k8s scheduler (other than default) + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param controller.terminationGracePeriodSeconds In seconds, time the given to the Metallb controller pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: 0 + ## @param controller.topologySpreadConstraints Topology Spread Constraints for pod assignment + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## The value is evaluated as a template + ## + topologySpreadConstraints: [] + ## Controller container resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param controller.resources.limits The resources limits for the container + ## @param controller.resources.requests The requested resources for the container + ## + resources: + ## Example: + ## limits: + ## cpu: 100m + ## memory: 100Mi + limits: {} + ## Examples: + ## requests: + ## cpu: 25m + ## memory: 25Mi + requests: {} + ## @param controller.nodeSelector Node labels for controller pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param controller.tolerations Tolerations for controller pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param controller.affinity Affinity for controller pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + ## @param controller.podAnnotations Controller Pod annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param controller.podLabels Controller Pod labels + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param controller.podAffinityPreset Controller Pod affinitypreset. Allowed values: soft, hard + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param controller.podAntiAffinityPreset Controller Pod anti affinitypreset. Allowed values: soft, hard + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## Allowed values: soft, hard + ## + nodeAffinityPreset: + ## @param controller.nodeAffinityPreset.type Controller Pod Node affinity preset. Allowed values: soft, hard + ## + type: "" + ## @param controller.nodeAffinityPreset.key Controller Pod Node affinity label key to match + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param controller.nodeAffinityPreset.values Controller Pod Node affinity label values to match + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## Configure Pods Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param controller.podSecurityContext.enabled Enabled Metallb Controller pods' Security Context + ## @param controller.podSecurityContext.fsGroup Set Metallb Controller pod's Security Context fsGroup + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + ## Configure Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param controller.containerSecurityContext.enabled Enabled Metallb Controller containers' Security Context + ## @param controller.containerSecurityContext.runAsUser Set Metallb Controller containers' Security Context runAsUser + ## @param controller.containerSecurityContext.runAsNonRoot Set Metallb Controller container's Security Context runAsNonRoot + ## @param controller.containerSecurityContext.allowPrivilegeEscalation Enables privilege Escalation context for the pod. + ## @param controller.containerSecurityContext.readOnlyRootFilesystem Allows the pod to mount the RootFS as ReadOnly + ## @param controller.containerSecurityContext.capabilities.drop [array] Drop capabilities for the securityContext + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + ## @param controller.command Override default container command (useful when using custom images) + ## + command: [] + ## @param controller.args Override default container args (useful when using custom images) + ## + args: [] + ## @param controller.lifecycleHooks for the Metallb Controller container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param controller.extraEnvVars Extra environment variable to pass to the running container. + ## For example: + ## extraEnvVars: + ## - name: MY_ENV_VAR + ## value: env_var_value + ## + extraEnvVars: [] + ## @param controller.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for Metallb controller nodes + ## + extraEnvVarsCM: "" + ## @param controller.extraEnvVarsSecret Name of existing Secret containing extra env vars for Metallb controller nodes + ## + extraEnvVarsSecret: "" + ## @param controller.extraVolumes Optionally specify extra list of additional volumes for the Metallb controller pod(s) + ## + extraVolumes: [] + ## @param controller.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the Metallb controller container(s) + ## + extraVolumeMounts: [] + ## @param controller.sidecars Add additional sidecar containers to the Metallb Controller pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param controller.initContainers Add additional init containers to the Metallb Controller pod(s) + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## initContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + initContainers: [] + ## Pods Service Account + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## @param controller.serviceAccount.create Specifies whether a ServiceAccount should be created + ## @param controller.serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template. + ## @param controller.serviceAccount.automountServiceAccountToken Automount service account token for the server service account + ## @param controller.serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if `create` is `true`. + ## + serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + annotations: {} + ## @param controller.revisionHistoryLimit Configure the revisionHistoryLimit of the Controller deployment + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#revision-history-limit + ## + revisionHistoryLimit: 3 + ## @param controller.containerPorts.metrics Configures the ports the MetalLB Controller listens on for metrics + ## + containerPorts: + metrics: 7472 + ## Liveness probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param controller.livenessProbe.enabled Enable livenessProbe + ## @param controller.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param controller.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param controller.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param controller.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param controller.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## Readiness probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param controller.readinessProbe.enabled Enable readinessProbe + ## @param controller.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param controller.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param controller.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param controller.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param controller.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## Startup probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param controller.startupProbe.enabled Enable startupProbe + ## @param controller.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param controller.startupProbe.periodSeconds Period seconds for startupProbe + ## @param controller.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param controller.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param controller.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## @param controller.customStartupProbe Custom liveness probe for the Web component + ## + customStartupProbe: {} + ## @param controller.customLivenessProbe Custom liveness probe for the Web component + ## + customLivenessProbe: {} + ## @param controller.customReadinessProbe Custom readiness probe for the Web component + ## + customReadinessProbe: {} + + ## @section Metallb controller Prometheus metrics export + ## + metrics: + ## @param controller.metrics.enabled Enable the export of Prometheus metrics + ## + enabled: false + ## Prometheus Exporter service parameters + ## + service: + ## @param controller.metrics.service.port Prometheus metrics service port + ## + port: 7472 + ## @param controller.metrics.service.annotations [object] Annotations for the Prometheus Exporter service service + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "7472" + prometheus.io/path: "/metrics" ## Prometheus Operator service monitors + ## + serviceMonitor: + ## @param controller.metrics.serviceMonitor.enabled Specify if a servicemonitor will be deployed for prometheus-operator + ## + enabled: false + ## @param controller.metrics.serviceMonitor.namespace Namespace which Prometheus is running in + ## e.g: + ## namespace: monitoring + ## + namespace: "" + ## @param controller.metrics.serviceMonitor.jobLabel Specify the jobLabel to use for the prometheus-operator + ## + jobLabel: "app.kubernetes.io/name" + ## @param controller.metrics.serviceMonitor.interval Scrape interval. If not set, the Prometheus default scrape interval is used + ## + interval: "" + ## @param controller.metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + scrapeTimeout: "" + ## @param controller.metrics.serviceMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param controller.metrics.serviceMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param controller.metrics.serviceMonitor.selector ServiceMonitor selector labels + ## ref: https://github.com/bitnami/charts/tree/master/bitnami/prometheus-operator#prometheus-configuration + ## + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param controller.metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + ## @param controller.metrics.serviceMonitor.honorLabels honorLabels chooses the metric's labels on collisions with target labels + ## + honorLabels: false + +## @section Speaker parameters + +## Metallb Speaker daemonset. +## ref: https://hub.docker.com/r/bitnami/metallb-speaker/tags +## +speaker: + ## @param speaker.image.registry MetalLB Speaker image registry + ## @param speaker.image.repository MetalLB Speaker image repository + ## @param speaker.image.tag MetalLB Speaker image tag (immutable tags are recommended) + ## @param speaker.image.pullPolicy MetalLB Speaker image pull policy + ## @param speaker.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/metallb-speaker + tag: 0.12.1-debian-11-r3 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param speaker.updateStrategy.type Speaker daemonset strategy type + ## ref: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/ + ## + updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate + ## If global .Values.rbac.create is disabled no rbac is created. + ## This value is then meaningless + ## Defines if the speaker rbac should be created. + ## + rbac: + ## @param speaker.rbac.create create specifies whether to install and use RBAC rules. + ## + create: true + ## @param speaker.hostAliases Deployment pod host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## If global .Values.psp.create is disabled no psp is created. + ## This value is then meaningless + ## Defines if the speaker psp should be created. + ## + psp: + ## @param speaker.psp.create Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later + ## + create: true + ## @param speaker.priorityClassName Speaker pods' priorityClassName + ## + priorityClassName: "" + ## @param speaker.terminationGracePeriodSeconds In seconds, time the given to the Speaker pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: 2 + ## Speaker container resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param speaker.resources.limits The resources limits for the container + ## @param speaker.resources.requests The requested resources for the container + ## + resources: + ## Example: + ## limits: + ## cpu: 100m + ## memory: 100Mi + limits: {} + ## Examples: + ## requests: + ## cpu: 25m + ## memory: 25Mi + requests: {} + ## @param speaker.nodeSelector Node labels for speaker pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param speaker.tolerations Tolerations for speaker pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param speaker.affinity Affinity for speaker pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + ## Node speaker.affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param speaker.nodeAffinityPreset.type Node affinity preset type. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param speaker.nodeAffinityPreset.key Node label key to match. Ignored if `speaker.affinity` is set + ## + key: "" + ## @param speaker.nodeAffinityPreset.values Node label values to match. Ignored if `speaker.affinity` is set + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param speaker.podAffinityPreset Pod affinity preset. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param speaker.podAntiAffinityPreset Pod anti-affinity preset. Ignored if `speaker.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## @param speaker.podAnnotations Speaker Pod annotations + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param speaker.podLabels Speaker Pod labels + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## Configure Pods Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param speaker.podSecurityContext.enabled Enabled Speaker pods' Security Context + ## @param speaker.podSecurityContext.fsGroup Set Speaker pod's Security Context fsGroup + ## + podSecurityContext: + enabled: true + fsGroup: 0 + ## Configure Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param speaker.containerSecurityContext.enabled Enabled Speaker containers' Security Context + ## @param speaker.containerSecurityContext.runAsUser Set Speaker containers' Security Context runAsUser + ## @param speaker.containerSecurityContext.allowPrivilegeEscalation Enables privilege Escalation context for the pod. + ## @param speaker.containerSecurityContext.readOnlyRootFilesystem Allows the pod to mount the RootFS as ReadOnly + ## @param speaker.containerSecurityContext.capabilities.drop [array] Drop capabilities for the securityContext + ## @param speaker.containerSecurityContext.capabilities.add [array] Add capabilities for the securityContext + ## + + containerSecurityContext: + enabled: true + runAsUser: 0 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + - NET_ADMIN + - NET_RAW + - SYS_ADMIN + ## @param speaker.command Override default container command (useful when using custom images) + ## + command: [] + ## @param speaker.args Override default container args (useful when using custom images) + ## + args: [] + ## @param speaker.lifecycleHooks for the Speaker container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param speaker.sidecars Add additional sidecar containers to the Speaker pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param speaker.initContainers Add additional init containers to the Speaker pod(s) + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## initContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + initContainers: [] + ## Pods Service Account + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## @param speaker.serviceAccount.create Specifies whether a ServiceAccount should be created + ## @param speaker.serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template. + ## @param speaker.serviceAccount.automountServiceAccountToken Automount service account token for the server service account + ## @param speaker.serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if `create` is `true`. + ## + serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + annotations: {} + ## Defines a secret to use outside of the auto generate + ## @param speaker.secretName References a Secret name for the member secret outside of the helm chart + ## @param speaker.secretKey References a Secret key the member secret outside of the helm chart + ## @param speaker.secretValue Custom value for `speaker.secretKey` + ## Default: {{ randAlphaNum 256 | b64enc | quote }} + ## The auto generated secret has: + ## secretName: {{ "common.names.fullname" }}-memberlist + ## secretKey: secretkey + ## secretValue: random 256 character alphanumeric string + ## + secretName: "" + secretKey: "" + secretValue: "" + ## @param speaker.extraEnvVars Extra environment variable to pass to the running container. + ## For example: + ## extraEnvVars: + ## - name: MY_ENV_VAR + ## value: env_var_value + ## + extraEnvVars: [] + ## @param speaker.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for Speaker nodes + ## + extraEnvVarsCM: "" + ## @param speaker.extraEnvVarsSecret Name of existing Secret containing extra env vars for Speaker nodes + ## + extraEnvVarsSecret: "" + ## @param speaker.extraVolumes Optionally specify extra list of additional volumes for the Speaker pod(s) + ## + extraVolumes: [] + ## @param speaker.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the Speaker container(s) + ## + extraVolumeMounts: [] + ## @param speaker.containerPorts.metrics HTTP Metrics Endpoint + ## + containerPorts: + metrics: 7472 + ## Liveness probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param speaker.livenessProbe.enabled Enable livenessProbe + ## @param speaker.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param speaker.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param speaker.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param speaker.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param speaker.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## Readiness probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param speaker.readinessProbe.enabled Enable readinessProbe + ## @param speaker.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param speaker.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param speaker.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param speaker.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param speaker.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## Startup probe values + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param speaker.startupProbe.enabled Enable startupProbe + ## @param speaker.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param speaker.startupProbe.periodSeconds Period seconds for startupProbe + ## @param speaker.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param speaker.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param speaker.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + ## @param speaker.customStartupProbe Custom liveness probe for the Web component + ## + customStartupProbe: {} + ## @param speaker.customLivenessProbe Custom liveness probe for the Web component + ## + customLivenessProbe: {} + ## @param speaker.customReadinessProbe Custom readiness probe for the Web component + ## + customReadinessProbe: {} + + ## @section Speaker Prometheus metrics export + metrics: + ## @param speaker.metrics.enabled Enable the export of Prometheus metrics + ## + enabled: false + ## Prometheus Exporter service parameters + ## + service: + ## @param speaker.metrics.service.port Prometheus metrics service port + ## + port: 7472 + ## @param speaker.metrics.service.annotations [object] Annotations for the Prometheus Exporter service service + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "7472" + prometheus.io/path: "/metrics" + ## Prometheus Operator service monitors + ## + serviceMonitor: + ## @param speaker.metrics.serviceMonitor.enabled Enable support for Prometheus Operator + ## + enabled: false + ## @param speaker.metrics.serviceMonitor.namespace Namespace which Prometheus is running in + ## e.g: + ## namespace: monitoring + ## + namespace: "" + ## @param speaker.metrics.serviceMonitor.jobLabel Job label for scrape target + ## + jobLabel: "app.kubernetes.io/name" + ## @param speaker.metrics.serviceMonitor.interval Scrape interval. If not set, the Prometheus default scrape interval is used + ## + interval: "" + ## @param speaker.metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + scrapeTimeout: "" + ## @param speaker.metrics.serviceMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param speaker.metrics.serviceMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param speaker.metrics.serviceMonitor.selector ServiceMonitor selector labels + ## ref: https://github.com/bitnami/charts/tree/master/bitnami/prometheus-operator#prometheus-configuration + ## + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param speaker.metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + ## @param speaker.metrics.serviceMonitor.honorLabels honorLabels chooses the metric's labels on collisions with target labels + ## + honorLabels: false From b0b1181ed550e932e270c8a03df29539da9a4bbd Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 11:26:42 +0400 Subject: [PATCH 02/17] sdasd --- apps/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/values.yaml b/apps/values.yaml index cd66cc0..54ca331 100644 --- a/apps/values.yaml +++ b/apps/values.yaml @@ -2,5 +2,5 @@ spec: destination: server: https://kubernetes.default.svc source: - repoURL: https://github.com/argoproj/argocd-example-apps + repoURL: https://github.com/aizekjerus/argocd-example-apps.git targetRevision: HEAD \ No newline at end of file From 470c91e3a1e6f3f5c8504d3d7ff5ff42ddc884f9 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 14:05:08 +0400 Subject: [PATCH 03/17] trrtr --- apps/templates/nginx-ingress.yaml | 16 + nginx-ingress/CHANGELOG.md | 398 ++++++++ nginx-ingress/Chart.yaml | 36 + nginx-ingress/OWNERS | 10 + nginx-ingress/README.md | 491 +++++++++ nginx-ingress/README.md.gotmpl | 235 +++++ .../controller-custom-ingressclass-flags.yaml | 7 + .../ci/daemonset-customconfig-values.yaml | 14 + .../ci/daemonset-customnodeport-values.yaml | 22 + nginx-ingress/ci/daemonset-extra-modules.yaml | 10 + .../ci/daemonset-headers-values.yaml | 14 + .../ci/daemonset-internal-lb-values.yaml | 14 + .../ci/daemonset-nodeport-values.yaml | 10 + .../ci/daemonset-podannotations-values.yaml | 17 + ...set-tcp-udp-configMapNamespace-values.yaml | 20 + ...emonset-tcp-udp-portNamePrefix-values.yaml | 18 + .../ci/daemonset-tcp-udp-values.yaml | 16 + nginx-ingress/ci/daemonset-tcp-values.yaml | 14 + .../ci/deamonset-default-values.yaml | 10 + .../ci/deamonset-metrics-values.yaml | 12 + nginx-ingress/ci/deamonset-psp-values.yaml | 13 + .../ci/deamonset-webhook-and-psp-values.yaml | 13 + .../ci/deamonset-webhook-values.yaml | 10 + ...eployment-autoscaling-behavior-values.yaml | 14 + .../ci/deployment-autoscaling-values.yaml | 11 + .../ci/deployment-customconfig-values.yaml | 12 + .../ci/deployment-customnodeport-values.yaml | 20 + .../ci/deployment-default-values.yaml | 8 + .../ci/deployment-extra-modules.yaml | 10 + .../ci/deployment-headers-values.yaml | 13 + .../ci/deployment-internal-lb-values.yaml | 13 + .../ci/deployment-metrics-values.yaml | 11 + .../ci/deployment-nodeport-values.yaml | 9 + .../ci/deployment-podannotations-values.yaml | 16 + nginx-ingress/ci/deployment-psp-values.yaml | 10 + ...ent-tcp-udp-configMapNamespace-values.yaml | 19 + ...loyment-tcp-udp-portNamePrefix-values.yaml | 17 + .../ci/deployment-tcp-udp-values.yaml | 15 + nginx-ingress/ci/deployment-tcp-values.yaml | 11 + .../ci/deployment-webhook-and-psp-values.yaml | 12 + .../deployment-webhook-resources-values.yaml | 23 + .../ci/deployment-webhook-values.yaml | 9 + nginx-ingress/templates/NOTES.txt | 80 ++ nginx-ingress/templates/_helpers.tpl | 185 ++++ nginx-ingress/templates/_params.tpl | 62 ++ .../job-patch/clusterrole.yaml | 34 + .../job-patch/clusterrolebinding.yaml | 23 + .../job-patch/job-createSecret.yaml | 76 ++ .../job-patch/job-patchWebhook.yaml | 78 ++ .../admission-webhooks/job-patch/psp.yaml | 39 + .../admission-webhooks/job-patch/role.yaml | 24 + .../job-patch/rolebinding.yaml | 24 + .../job-patch/serviceaccount.yaml | 16 + .../validating-webhook.yaml | 48 + nginx-ingress/templates/clusterrole.yaml | 87 ++ .../templates/clusterrolebinding.yaml | 19 + .../controller-configmap-addheaders.yaml | 14 + .../controller-configmap-proxyheaders.yaml | 19 + .../templates/controller-configmap-tcp.yaml | 17 + .../templates/controller-configmap-udp.yaml | 17 + .../templates/controller-configmap.yaml | 29 + .../templates/controller-daemonset.yaml | 223 +++++ .../templates/controller-deployment.yaml | 228 +++++ nginx-ingress/templates/controller-hpa.yaml | 52 + .../templates/controller-ingressclass.yaml | 21 + nginx-ingress/templates/controller-keda.yaml | 42 + .../controller-poddisruptionbudget.yaml | 19 + .../templates/controller-prometheusrules.yaml | 21 + nginx-ingress/templates/controller-psp.yaml | 92 ++ nginx-ingress/templates/controller-role.yaml | 93 ++ .../templates/controller-rolebinding.yaml | 21 + .../controller-service-internal.yaml | 79 ++ .../templates/controller-service-metrics.yaml | 45 + .../templates/controller-service-webhook.yaml | 40 + .../templates/controller-service.yaml | 101 ++ .../templates/controller-serviceaccount.yaml | 18 + .../templates/controller-servicemonitor.yaml | 48 + .../templates/default-backend-deployment.yaml | 118 +++ .../templates/default-backend-hpa.yaml | 33 + .../default-backend-poddisruptionbudget.yaml | 21 + .../templates/default-backend-psp.yaml | 36 + .../templates/default-backend-role.yaml | 22 + .../default-backend-rolebinding.yaml | 21 + .../templates/default-backend-service.yaml | 41 + .../default-backend-serviceaccount.yaml | 14 + nginx-ingress/templates/dh-param-secret.yaml | 10 + nginx-ingress/values.yaml | 931 ++++++++++++++++++ 87 files changed, 4954 insertions(+) create mode 100644 apps/templates/nginx-ingress.yaml create mode 100644 nginx-ingress/CHANGELOG.md create mode 100644 nginx-ingress/Chart.yaml create mode 100644 nginx-ingress/OWNERS create mode 100644 nginx-ingress/README.md create mode 100644 nginx-ingress/README.md.gotmpl create mode 100644 nginx-ingress/ci/controller-custom-ingressclass-flags.yaml create mode 100644 nginx-ingress/ci/daemonset-customconfig-values.yaml create mode 100644 nginx-ingress/ci/daemonset-customnodeport-values.yaml create mode 100644 nginx-ingress/ci/daemonset-extra-modules.yaml create mode 100644 nginx-ingress/ci/daemonset-headers-values.yaml create mode 100644 nginx-ingress/ci/daemonset-internal-lb-values.yaml create mode 100644 nginx-ingress/ci/daemonset-nodeport-values.yaml create mode 100644 nginx-ingress/ci/daemonset-podannotations-values.yaml create mode 100644 nginx-ingress/ci/daemonset-tcp-udp-configMapNamespace-values.yaml create mode 100644 nginx-ingress/ci/daemonset-tcp-udp-portNamePrefix-values.yaml create mode 100644 nginx-ingress/ci/daemonset-tcp-udp-values.yaml create mode 100644 nginx-ingress/ci/daemonset-tcp-values.yaml create mode 100644 nginx-ingress/ci/deamonset-default-values.yaml create mode 100644 nginx-ingress/ci/deamonset-metrics-values.yaml create mode 100644 nginx-ingress/ci/deamonset-psp-values.yaml create mode 100644 nginx-ingress/ci/deamonset-webhook-and-psp-values.yaml create mode 100644 nginx-ingress/ci/deamonset-webhook-values.yaml create mode 100644 nginx-ingress/ci/deployment-autoscaling-behavior-values.yaml create mode 100644 nginx-ingress/ci/deployment-autoscaling-values.yaml create mode 100644 nginx-ingress/ci/deployment-customconfig-values.yaml create mode 100644 nginx-ingress/ci/deployment-customnodeport-values.yaml create mode 100644 nginx-ingress/ci/deployment-default-values.yaml create mode 100644 nginx-ingress/ci/deployment-extra-modules.yaml create mode 100644 nginx-ingress/ci/deployment-headers-values.yaml create mode 100644 nginx-ingress/ci/deployment-internal-lb-values.yaml create mode 100644 nginx-ingress/ci/deployment-metrics-values.yaml create mode 100644 nginx-ingress/ci/deployment-nodeport-values.yaml create mode 100644 nginx-ingress/ci/deployment-podannotations-values.yaml create mode 100644 nginx-ingress/ci/deployment-psp-values.yaml create mode 100644 nginx-ingress/ci/deployment-tcp-udp-configMapNamespace-values.yaml create mode 100644 nginx-ingress/ci/deployment-tcp-udp-portNamePrefix-values.yaml create mode 100644 nginx-ingress/ci/deployment-tcp-udp-values.yaml create mode 100644 nginx-ingress/ci/deployment-tcp-values.yaml create mode 100644 nginx-ingress/ci/deployment-webhook-and-psp-values.yaml create mode 100644 nginx-ingress/ci/deployment-webhook-resources-values.yaml create mode 100644 nginx-ingress/ci/deployment-webhook-values.yaml create mode 100644 nginx-ingress/templates/NOTES.txt create mode 100644 nginx-ingress/templates/_helpers.tpl create mode 100644 nginx-ingress/templates/_params.tpl create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/clusterrole.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/clusterrolebinding.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/job-createSecret.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/job-patchWebhook.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/psp.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/role.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/rolebinding.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/job-patch/serviceaccount.yaml create mode 100644 nginx-ingress/templates/admission-webhooks/validating-webhook.yaml create mode 100644 nginx-ingress/templates/clusterrole.yaml create mode 100644 nginx-ingress/templates/clusterrolebinding.yaml create mode 100644 nginx-ingress/templates/controller-configmap-addheaders.yaml create mode 100644 nginx-ingress/templates/controller-configmap-proxyheaders.yaml create mode 100644 nginx-ingress/templates/controller-configmap-tcp.yaml create mode 100644 nginx-ingress/templates/controller-configmap-udp.yaml create mode 100644 nginx-ingress/templates/controller-configmap.yaml create mode 100644 nginx-ingress/templates/controller-daemonset.yaml create mode 100644 nginx-ingress/templates/controller-deployment.yaml create mode 100644 nginx-ingress/templates/controller-hpa.yaml create mode 100644 nginx-ingress/templates/controller-ingressclass.yaml create mode 100644 nginx-ingress/templates/controller-keda.yaml create mode 100644 nginx-ingress/templates/controller-poddisruptionbudget.yaml create mode 100644 nginx-ingress/templates/controller-prometheusrules.yaml create mode 100644 nginx-ingress/templates/controller-psp.yaml create mode 100644 nginx-ingress/templates/controller-role.yaml create mode 100644 nginx-ingress/templates/controller-rolebinding.yaml create mode 100644 nginx-ingress/templates/controller-service-internal.yaml create mode 100644 nginx-ingress/templates/controller-service-metrics.yaml create mode 100644 nginx-ingress/templates/controller-service-webhook.yaml create mode 100644 nginx-ingress/templates/controller-service.yaml create mode 100644 nginx-ingress/templates/controller-serviceaccount.yaml create mode 100644 nginx-ingress/templates/controller-servicemonitor.yaml create mode 100644 nginx-ingress/templates/default-backend-deployment.yaml create mode 100644 nginx-ingress/templates/default-backend-hpa.yaml create mode 100644 nginx-ingress/templates/default-backend-poddisruptionbudget.yaml create mode 100644 nginx-ingress/templates/default-backend-psp.yaml create mode 100644 nginx-ingress/templates/default-backend-role.yaml create mode 100644 nginx-ingress/templates/default-backend-rolebinding.yaml create mode 100644 nginx-ingress/templates/default-backend-service.yaml create mode 100644 nginx-ingress/templates/default-backend-serviceaccount.yaml create mode 100644 nginx-ingress/templates/dh-param-secret.yaml create mode 100644 nginx-ingress/values.yaml diff --git a/apps/templates/nginx-ingress.yaml b/apps/templates/nginx-ingress.yaml new file mode 100644 index 0000000..d64a205 --- /dev/null +++ b/apps/templates/nginx-ingress.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx-ingress + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: nginx-ingress + server: {{ .Values.spec.destination.server }} + project: default + source: + path: nginx-ingress + repoURL: {{ .Values.spec.source.repoURL }} + targetRevision: {{ .Values.spec.source.targetRevision }} diff --git a/nginx-ingress/CHANGELOG.md b/nginx-ingress/CHANGELOG.md new file mode 100644 index 0000000..201a4f0 --- /dev/null +++ b/nginx-ingress/CHANGELOG.md @@ -0,0 +1,398 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.1.2 + +- "[8587](https://github.com/kubernetes/ingress-nginx/pull/8587) Add CAP_SYS_CHROOT to DS/PSP when needed" +- "[8458](https://github.com/kubernetes/ingress-nginx/pull/8458) Add portNamePreffix Helm chart parameter" +- "[8522](https://github.com/kubernetes/ingress-nginx/pull/8522) Add documentation for controller.service.loadBalancerIP in Helm chart" + +### 4.1.0 + +- "[8481](https://github.com/kubernetes/ingress-nginx/pull/8481) Fix log creation in chroot script" +- "[8479](https://github.com/kubernetes/ingress-nginx/pull/8479) changed nginx base img tag to img built with alpine3.14.6" +- "[8478](https://github.com/kubernetes/ingress-nginx/pull/8478) update base images and protobuf gomod" +- "[8468](https://github.com/kubernetes/ingress-nginx/pull/8468) Fallback to ngx.var.scheme for redirectScheme with use-forward-headers when X-Forwarded-Proto is empty" +- "[8456](https://github.com/kubernetes/ingress-nginx/pull/8456) Implement object deep inspector" +- "[8455](https://github.com/kubernetes/ingress-nginx/pull/8455) Update dependencies" +- "[8454](https://github.com/kubernetes/ingress-nginx/pull/8454) Update index.md" +- "[8447](https://github.com/kubernetes/ingress-nginx/pull/8447) typo fixing" +- "[8446](https://github.com/kubernetes/ingress-nginx/pull/8446) Fix suggested annotation-value-word-blocklist" +- "[8444](https://github.com/kubernetes/ingress-nginx/pull/8444) replace deprecated topology key in example with current one" +- "[8443](https://github.com/kubernetes/ingress-nginx/pull/8443) Add dependency review enforcement" +- "[8434](https://github.com/kubernetes/ingress-nginx/pull/8434) added new auth-tls-match-cn annotation" +- "[8426](https://github.com/kubernetes/ingress-nginx/pull/8426) Bump github.com/prometheus/common from 0.32.1 to 0.33.0" + +### 4.0.18 + +- "[8291](https://github.com/kubernetes/ingress-nginx/pull/8291) remove git tag env from cloud build" +- "[8286](https://github.com/kubernetes/ingress-nginx/pull/8286) Fix OpenTelemetry sidecar image build" +- "[8277](https://github.com/kubernetes/ingress-nginx/pull/8277) Add OpenSSF Best practices badge" +- "[8273](https://github.com/kubernetes/ingress-nginx/pull/8273) Issue#8241" +- "[8267](https://github.com/kubernetes/ingress-nginx/pull/8267) Add fsGroup value to admission-webhooks/job-patch charts" +- "[8262](https://github.com/kubernetes/ingress-nginx/pull/8262) Updated confusing error" +- "[8256](https://github.com/kubernetes/ingress-nginx/pull/8256) fix: deny locations with invalid auth-url annotation" +- "[8253](https://github.com/kubernetes/ingress-nginx/pull/8253) Add a certificate info metric" +- "[8236](https://github.com/kubernetes/ingress-nginx/pull/8236) webhook: remove useless code." +- "[8227](https://github.com/kubernetes/ingress-nginx/pull/8227) Update libraries in webhook image" +- "[8225](https://github.com/kubernetes/ingress-nginx/pull/8225) fix inconsistent-label-cardinality for prometheus metrics: nginx_ingress_controller_requests" +- "[8221](https://github.com/kubernetes/ingress-nginx/pull/8221) Do not validate ingresses with unknown ingress class in admission webhook endpoint" +- "[8210](https://github.com/kubernetes/ingress-nginx/pull/8210) Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.1" +- "[8209](https://github.com/kubernetes/ingress-nginx/pull/8209) Bump google.golang.org/grpc from 1.43.0 to 1.44.0" +- "[8204](https://github.com/kubernetes/ingress-nginx/pull/8204) Add Artifact Hub lint" +- "[8203](https://github.com/kubernetes/ingress-nginx/pull/8203) Fix Indentation of example and link to cert-manager tutorial" +- "[8201](https://github.com/kubernetes/ingress-nginx/pull/8201) feat(metrics): add path and method labels to requests countera" +- "[8199](https://github.com/kubernetes/ingress-nginx/pull/8199) use functional options to reduce number of methods creating an EchoDeployment" +- "[8196](https://github.com/kubernetes/ingress-nginx/pull/8196) docs: fix inconsistent controller annotation" +- "[8191](https://github.com/kubernetes/ingress-nginx/pull/8191) Using Go install for misspell" +- "[8186](https://github.com/kubernetes/ingress-nginx/pull/8186) prometheus+grafana using servicemonitor" +- "[8185](https://github.com/kubernetes/ingress-nginx/pull/8185) Append elements on match, instead of removing for cors-annotations" +- "[8179](https://github.com/kubernetes/ingress-nginx/pull/8179) Bump github.com/opencontainers/runc from 1.0.3 to 1.1.0" +- "[8173](https://github.com/kubernetes/ingress-nginx/pull/8173) Adding annotations to the controller service account" +- "[8163](https://github.com/kubernetes/ingress-nginx/pull/8163) Update the $req_id placeholder description" +- "[8162](https://github.com/kubernetes/ingress-nginx/pull/8162) Versioned static manifests" +- "[8159](https://github.com/kubernetes/ingress-nginx/pull/8159) Adding some geoip variables and default values" +- "[8155](https://github.com/kubernetes/ingress-nginx/pull/8155) #7271 feat: avoid-pdb-creation-when-default-backend-disabled-and-replicas-gt-1" +- "[8151](https://github.com/kubernetes/ingress-nginx/pull/8151) Automatically generate helm docs" +- "[8143](https://github.com/kubernetes/ingress-nginx/pull/8143) Allow to configure delay before controller exits" +- "[8136](https://github.com/kubernetes/ingress-nginx/pull/8136) add ingressClass option to helm chart - back compatibility with ingress.class annotations" +- "[8126](https://github.com/kubernetes/ingress-nginx/pull/8126) Example for JWT" + + +### 4.0.15 + +- [8120] https://github.com/kubernetes/ingress-nginx/pull/8120 Update go in runner and release v1.1.1 +- [8119] https://github.com/kubernetes/ingress-nginx/pull/8119 Update to go v1.17.6 +- [8118] https://github.com/kubernetes/ingress-nginx/pull/8118 Remove deprecated libraries, update other libs +- [8117] https://github.com/kubernetes/ingress-nginx/pull/8117 Fix codegen errors +- [8115] https://github.com/kubernetes/ingress-nginx/pull/8115 chart/ghaction: set the correct permission to have access to push a release +- [8098] https://github.com/kubernetes/ingress-nginx/pull/8098 generating SHA for CA only certs in backend_ssl.go + comparision of P… +- [8088] https://github.com/kubernetes/ingress-nginx/pull/8088 Fix Edit this page link to use main branch +- [8072] https://github.com/kubernetes/ingress-nginx/pull/8072 Expose GeoIP2 Continent code as variable +- [8061] https://github.com/kubernetes/ingress-nginx/pull/8061 docs(charts): using helm-docs for chart +- [8058] https://github.com/kubernetes/ingress-nginx/pull/8058 Bump github.com/spf13/cobra from 1.2.1 to 1.3.0 +- [8054] https://github.com/kubernetes/ingress-nginx/pull/8054 Bump google.golang.org/grpc from 1.41.0 to 1.43.0 +- [8051] https://github.com/kubernetes/ingress-nginx/pull/8051 align bug report with feature request regarding kind documentation +- [8046] https://github.com/kubernetes/ingress-nginx/pull/8046 Report expired certificates (#8045) +- [8044] https://github.com/kubernetes/ingress-nginx/pull/8044 remove G109 check till gosec resolves issues +- [8042] https://github.com/kubernetes/ingress-nginx/pull/8042 docs_multiple_instances_one_cluster_ticket_7543 +- [8041] https://github.com/kubernetes/ingress-nginx/pull/8041 docs: fix typo'd executible name +- [8035] https://github.com/kubernetes/ingress-nginx/pull/8035 Comment busy owners +- [8029] https://github.com/kubernetes/ingress-nginx/pull/8029 Add stream-snippet as a ConfigMap and Annotation option +- [8023] https://github.com/kubernetes/ingress-nginx/pull/8023 fix nginx compilation flags +- [8021] https://github.com/kubernetes/ingress-nginx/pull/8021 Disable default modsecurity_rules_file if modsecurity-snippet is specified +- [8019] https://github.com/kubernetes/ingress-nginx/pull/8019 Revise main documentation page +- [8018] https://github.com/kubernetes/ingress-nginx/pull/8018 Preserve order of plugin invocation +- [8015] https://github.com/kubernetes/ingress-nginx/pull/8015 Add newline indenting to admission webhook annotations +- [8014] https://github.com/kubernetes/ingress-nginx/pull/8014 Add link to example error page manifest in docs +- [8009] https://github.com/kubernetes/ingress-nginx/pull/8009 Fix spelling in documentation and top-level files +- [8008] https://github.com/kubernetes/ingress-nginx/pull/8008 Add relabelings in controller-servicemonitor.yaml +- [8003] https://github.com/kubernetes/ingress-nginx/pull/8003 Minor improvements (formatting, consistency) in install guide +- [8001] https://github.com/kubernetes/ingress-nginx/pull/8001 fix: go-grpc Dockerfile +- [7999] https://github.com/kubernetes/ingress-nginx/pull/7999 images: use k8s-staging-test-infra/gcb-docker-gcloud +- [7996] https://github.com/kubernetes/ingress-nginx/pull/7996 doc: improvement +- [7983] https://github.com/kubernetes/ingress-nginx/pull/7983 Fix a couple of misspellings in the annotations documentation. +- [7979] https://github.com/kubernetes/ingress-nginx/pull/7979 allow set annotations for admission Jobs +- [7977] https://github.com/kubernetes/ingress-nginx/pull/7977 Add ssl_reject_handshake to defaul server +- [7975] https://github.com/kubernetes/ingress-nginx/pull/7975 add legacy version update v0.50.0 to main changelog +- [7972] https://github.com/kubernetes/ingress-nginx/pull/7972 updated service upstream definition + +### 4.0.14 + +- [8061] https://github.com/kubernetes/ingress-nginx/pull/8061 Using helm-docs to populate values table in README.md + +### 4.0.13 + +- [8008] https://github.com/kubernetes/ingress-nginx/pull/8008 Add relabelings in controller-servicemonitor.yaml + +### 4.0.12 + +- [7978] https://github.com/kubernetes/ingress-nginx/pull/7979 Support custom annotations in admissions Jobs + +### 4.0.11 + +- [7873] https://github.com/kubernetes/ingress-nginx/pull/7873 Makes the [appProtocol](https://kubernetes.io/docs/concepts/services-networking/_print/#application-protocol) field optional. + +### 4.0.10 + +- [7964] https://github.com/kubernetes/ingress-nginx/pull/7964 Update controller version to v1.1.0 + +### 4.0.9 + +- [6992] https://github.com/kubernetes/ingress-nginx/pull/6992 Add ability to specify labels for all resources + +### 4.0.7 + +- [7923] https://github.com/kubernetes/ingress-nginx/pull/7923 Release v1.0.5 of ingress-nginx +- [7806] https://github.com/kubernetes/ingress-nginx/pull/7806 Choice option for internal/external loadbalancer type service + +### 4.0.6 + +- [7804] https://github.com/kubernetes/ingress-nginx/pull/7804 Release v1.0.4 of ingress-nginx +- [7651] https://github.com/kubernetes/ingress-nginx/pull/7651 Support ipFamilyPolicy and ipFamilies fields in Helm Chart +- [7798] https://github.com/kubernetes/ingress-nginx/pull/7798 Exoscale: use HTTP Healthcheck mode +- [7793] https://github.com/kubernetes/ingress-nginx/pull/7793 Update kube-webhook-certgen to v1.1.1 + +### 4.0.5 + +- [7740] https://github.com/kubernetes/ingress-nginx/pull/7740 Release v1.0.3 of ingress-nginx + +### 4.0.3 + +- [7707] https://github.com/kubernetes/ingress-nginx/pull/7707 Release v1.0.2 of ingress-nginx + +### 4.0.2 + +- [7681] https://github.com/kubernetes/ingress-nginx/pull/7681 Release v1.0.1 of ingress-nginx + +### 4.0.1 + +- [7535] https://github.com/kubernetes/ingress-nginx/pull/7535 Release v1.0.0 ingress-nginx + +### 3.34.0 + +- [7256] https://github.com/kubernetes/ingress-nginx/pull/7256 Add namespace field in the namespace scoped resource templates + +### 3.33.0 + +- [7164] https://github.com/kubernetes/ingress-nginx/pull/7164 Update nginx to v1.20.1 + +### 3.32.0 + +- [7117] https://github.com/kubernetes/ingress-nginx/pull/7117 Add annotations for HPA + +### 3.31.0 + +- [7137] https://github.com/kubernetes/ingress-nginx/pull/7137 Add support for custom probes + +### 3.30.0 + +- [#7092](https://github.com/kubernetes/ingress-nginx/pull/7092) Removes the possibility of using localhost in ExternalNames as endpoints + +### 3.29.0 + +- [X] [#6945](https://github.com/kubernetes/ingress-nginx/pull/7020) Add option to specify job label for ServiceMonitor + +### 3.28.0 + +- [ ] [#6900](https://github.com/kubernetes/ingress-nginx/pull/6900) Support existing PSPs + +### 3.27.0 + +- Update ingress-nginx v0.45.0 + +### 3.26.0 + +- [X] [#6979](https://github.com/kubernetes/ingress-nginx/pull/6979) Changed servicePort value for metrics + +### 3.25.0 + +- [X] [#6957](https://github.com/kubernetes/ingress-nginx/pull/6957) Add ability to specify automountServiceAccountToken + +### 3.24.0 + +- [X] [#6908](https://github.com/kubernetes/ingress-nginx/pull/6908) Add volumes to default-backend deployment + +### 3.23.0 + +- Update ingress-nginx v0.44.0 + +### 3.22.0 + +- [X] [#6802](https://github.com/kubernetes/ingress-nginx/pull/6802) Add value for configuring a custom Diffie-Hellman parameters file +- [X] [#6815](https://github.com/kubernetes/ingress-nginx/pull/6815) Allow use of numeric namespaces in helm chart + +### 3.21.0 + +- [X] [#6783](https://github.com/kubernetes/ingress-nginx/pull/6783) Add custom annotations to ScaledObject +- [X] [#6761](https://github.com/kubernetes/ingress-nginx/pull/6761) Adding quotes in the serviceAccount name in Helm values +- [X] [#6767](https://github.com/kubernetes/ingress-nginx/pull/6767) Remove ClusterRole when scope option is enabled +- [X] [#6785](https://github.com/kubernetes/ingress-nginx/pull/6785) Update kube-webhook-certgen image to v1.5.1 + +### 3.20.1 + +- Do not create KEDA in case of DaemonSets. +- Fix KEDA v2 definition + +### 3.20.0 + +- [X] [#6730](https://github.com/kubernetes/ingress-nginx/pull/6730) Do not create HPA for defaultBackend if not enabled. + +### 3.19.0 + +- Update ingress-nginx v0.43.0 + +### 3.18.0 + +- [X] [#6688](https://github.com/kubernetes/ingress-nginx/pull/6688) Allow volume-type emptyDir in controller podsecuritypolicy +- [X] [#6691](https://github.com/kubernetes/ingress-nginx/pull/6691) Improve parsing of helm parameters + +### 3.17.0 + +- Update ingress-nginx v0.42.0 + +### 3.16.1 + +- Fix chart-releaser action + +### 3.16.0 + +- [X] [#6646](https://github.com/kubernetes/ingress-nginx/pull/6646) Added LoadBalancerIP value for internal service + +### 3.15.1 + +- Fix chart-releaser action + +### 3.15.0 + +- [X] [#6586](https://github.com/kubernetes/ingress-nginx/pull/6586) Fix 'maxmindLicenseKey' location in values.yaml + +### 3.14.0 + +- [X] [#6469](https://github.com/kubernetes/ingress-nginx/pull/6469) Allow custom service names for controller and backend + +### 3.13.0 + +- [X] [#6544](https://github.com/kubernetes/ingress-nginx/pull/6544) Fix default backend HPA name variable + +### 3.12.0 + +- [X] [#6514](https://github.com/kubernetes/ingress-nginx/pull/6514) Remove helm2 support and update docs + +### 3.11.1 + +- [X] [#6505](https://github.com/kubernetes/ingress-nginx/pull/6505) Reorder HPA resource list to work with GitOps tooling + +### 3.11.0 + +- Support Keda Autoscaling + +### 3.10.1 + +- Fix regression introduced in 0.41.0 with external authentication + +### 3.10.0 + +- Fix routing regression introduced in 0.41.0 with PathType Exact + +### 3.9.0 + +- [X] [#6423](https://github.com/kubernetes/ingress-nginx/pull/6423) Add Default backend HPA autoscaling + +### 3.8.0 + +- [X] [#6395](https://github.com/kubernetes/ingress-nginx/pull/6395) Update jettech/kube-webhook-certgen image +- [X] [#6377](https://github.com/kubernetes/ingress-nginx/pull/6377) Added loadBalancerSourceRanges for internal lbs +- [X] [#6356](https://github.com/kubernetes/ingress-nginx/pull/6356) Add securitycontext settings on defaultbackend +- [X] [#6401](https://github.com/kubernetes/ingress-nginx/pull/6401) Fix controller service annotations +- [X] [#6403](https://github.com/kubernetes/ingress-nginx/pull/6403) Initial helm chart changelog + +### 3.7.1 + +- [X] [#6326](https://github.com/kubernetes/ingress-nginx/pull/6326) Fix liveness and readiness probe path in daemonset chart + +### 3.7.0 + +- [X] [#6316](https://github.com/kubernetes/ingress-nginx/pull/6316) Numerals in podAnnotations in quotes [#6315](https://github.com/kubernetes/ingress-nginx/issues/6315) + +### 3.6.0 + +- [X] [#6305](https://github.com/kubernetes/ingress-nginx/pull/6305) Add default linux nodeSelector + +### 3.5.1 + +- [X] [#6299](https://github.com/kubernetes/ingress-nginx/pull/6299) Fix helm chart release + +### 3.5.0 + +- [X] [#6260](https://github.com/kubernetes/ingress-nginx/pull/6260) Allow Helm Chart to customize admission webhook's annotations, timeoutSeconds, namespaceSelector, objectSelector and cert files locations + +### 3.4.0 + +- [X] [#6268](https://github.com/kubernetes/ingress-nginx/pull/6268) Update to 0.40.2 in helm chart #6288 + +### 3.3.1 + +- [X] [#6259](https://github.com/kubernetes/ingress-nginx/pull/6259) Release helm chart +- [X] [#6258](https://github.com/kubernetes/ingress-nginx/pull/6258) Fix chart markdown link +- [X] [#6253](https://github.com/kubernetes/ingress-nginx/pull/6253) Release v0.40.0 + +### 3.3.1 + +- [X] [#6233](https://github.com/kubernetes/ingress-nginx/pull/6233) Add admission controller e2e test + +### 3.3.0 + +- [X] [#6203](https://github.com/kubernetes/ingress-nginx/pull/6203) Refactor parsing of key values +- [X] [#6162](https://github.com/kubernetes/ingress-nginx/pull/6162) Add helm chart options to expose metrics service as NodePort +- [X] [#6180](https://github.com/kubernetes/ingress-nginx/pull/6180) Fix helm chart admissionReviewVersions regression +- [X] [#6169](https://github.com/kubernetes/ingress-nginx/pull/6169) Fix Typo in example prometheus rules + +### 3.0.0 + +- [X] [#6167](https://github.com/kubernetes/ingress-nginx/pull/6167) Update chart requirements + +### 2.16.0 + +- [X] [#6154](https://github.com/kubernetes/ingress-nginx/pull/6154) add `topologySpreadConstraint` to controller + +### 2.15.0 + +- [X] [#6087](https://github.com/kubernetes/ingress-nginx/pull/6087) Adding parameter for externalTrafficPolicy in internal controller service spec + +### 2.14.0 + +- [X] [#6104](https://github.com/kubernetes/ingress-nginx/pull/6104) Misc fixes for nginx-ingress chart for better keel and prometheus-operator integration + +### 2.13.0 + +- [X] [#6093](https://github.com/kubernetes/ingress-nginx/pull/6093) Release v0.35.0 + +### 2.13.0 + +- [X] [#6093](https://github.com/kubernetes/ingress-nginx/pull/6093) Release v0.35.0 +- [X] [#6080](https://github.com/kubernetes/ingress-nginx/pull/6080) Switch images to k8s.gcr.io after Vanity Domain Flip + +### 2.12.1 + +- [X] [#6075](https://github.com/kubernetes/ingress-nginx/pull/6075) Sync helm chart affinity examples + +### 2.12.0 + +- [X] [#6039](https://github.com/kubernetes/ingress-nginx/pull/6039) Add configurable serviceMonitor metricRelabelling and targetLabels +- [X] [#6044](https://github.com/kubernetes/ingress-nginx/pull/6044) Fix YAML linting + +### 2.11.3 + +- [X] [#6038](https://github.com/kubernetes/ingress-nginx/pull/6038) Bump chart version PATCH + +### 2.11.2 + +- [X] [#5951](https://github.com/kubernetes/ingress-nginx/pull/5951) Bump chart patch version + +### 2.11.1 + +- [X] [#5900](https://github.com/kubernetes/ingress-nginx/pull/5900) Release helm chart for v0.34.1 + +### 2.11.0 + +- [X] [#5879](https://github.com/kubernetes/ingress-nginx/pull/5879) Update helm chart for v0.34.0 +- [X] [#5671](https://github.com/kubernetes/ingress-nginx/pull/5671) Make liveness probe more fault tolerant than readiness probe + +### 2.10.0 + +- [X] [#5843](https://github.com/kubernetes/ingress-nginx/pull/5843) Update jettech/kube-webhook-certgen image + +### 2.9.1 + +- [X] [#5823](https://github.com/kubernetes/ingress-nginx/pull/5823) Add quoting to sysctls because numeric values need to be presented as strings (#5823) + +### 2.9.0 + +- [X] [#5795](https://github.com/kubernetes/ingress-nginx/pull/5795) Use fully qualified images to avoid cri-o issues + + +### TODO + +Keep building the changelog using *git log charts* checking the tag diff --git a/nginx-ingress/Chart.yaml b/nginx-ingress/Chart.yaml new file mode 100644 index 0000000..0f2d3b3 --- /dev/null +++ b/nginx-ingress/Chart.yaml @@ -0,0 +1,36 @@ +apiVersion: v2 +name: ingress-nginx +# When the version is modified, make sure the artifacthub.io/changes list is updated +# Also update CHANGELOG.md +version: 4.1.4 +appVersion: 1.2.1 +home: https://github.com/kubernetes/ingress-nginx +description: Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer +icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png +keywords: + - ingress + - nginx +sources: + - https://github.com/kubernetes/ingress-nginx +type: application +maintainers: + - name: rikatz + - name: strongjz + - name: tao12345666333 +engine: gotpl +kubeVersion: ">=1.19.0-0" +annotations: + # Use this annotation to indicate that this chart version is a pre-release. + # https://artifacthub.io/docs/topics/annotations/helm/ + artifacthub.io/prerelease: "false" + # List of changes for the release in artifacthub.io + # https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx?modal=changelog + artifacthub.io/changes: | + - "[8459](https://github.com/kubernetes/ingress-nginx/pull/8459) Update default allowed CORS headers" + - "[8202](https://github.com/kubernetes/ingress-nginx/pull/8202) disable modsecurity on error page" + - "[8178](https://github.com/kubernetes/ingress-nginx/pull/8178) Add header Host into mirror annotations" + - "[8213](https://github.com/kubernetes/ingress-nginx/pull/8213) feat: always set auth cookie" + - "[8548](https://github.com/kubernetes/ingress-nginx/pull/8548) Implement reporting status classes in metrics" + - "[8612](https://github.com/kubernetes/ingress-nginx/pull/8612) move so files under /etc/nginx/modules" + - "[8624](https://github.com/kubernetes/ingress-nginx/pull/8624) Add patch to remove root and alias directives" + - "[8623](https://github.com/kubernetes/ingress-nginx/pull/8623) Improve path rule" diff --git a/nginx-ingress/OWNERS b/nginx-ingress/OWNERS new file mode 100644 index 0000000..6b7e049 --- /dev/null +++ b/nginx-ingress/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md + +approvers: +- ingress-nginx-helm-maintainers + +reviewers: +- ingress-nginx-helm-reviewers + +labels: +- area/helm diff --git a/nginx-ingress/README.md b/nginx-ingress/README.md new file mode 100644 index 0000000..c513f81 --- /dev/null +++ b/nginx-ingress/README.md @@ -0,0 +1,491 @@ +# ingress-nginx + +[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer + +![Version: 4.1.4](https://img.shields.io/badge/Version-4.1.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.2.1](https://img.shields.io/badge/AppVersion-1.2.1-informational?style=flat-square) + +To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources. + +This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Chart version 3.x.x: Kubernetes v1.16+ +- Chart version 4.x.x and above: Kubernetes v1.19+ + +## Get Repo Info + +```console +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +``` + +## Install Chart + +**Important:** only helm3 is supported + +```console +helm install [RELEASE_NAME] ingress-nginx/ingress-nginx +``` + +The command deploys ingress-nginx on the Kubernetes cluster in the default configuration. + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading With Zero Downtime in Production + +By default the ingress-nginx controller has service interruptions whenever it's pods are restarted or redeployed. In order to fix that, see the excellent blog post by Lindsay Landry from Codecademy: [Kubernetes: Nginx and Zero Downtime in Production](https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8). + +### Migrating from stable/nginx-ingress + +There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: + +1. For Nginx Ingress controllers used for non-critical services, the easiest method is to [uninstall](#uninstall-chart) the old release and [install](#install-chart) the new one +1. For critical services in production that require zero-downtime, you will want to: + 1. [Install](#install-chart) a second Ingress controller + 1. Redirect your DNS traffic from the old controller to the new controller + 1. Log traffic from both controllers during this changeover + 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it + 1. For details on all of these steps see [Upgrading With Zero Downtime in Production](#upgrading-with-zero-downtime-in-production) + +Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values ingress-nginx/ingress-nginx +``` + +### PodDisruptionBudget + +Note that the PodDisruptionBudget resource will only be defined if the replicaCount is greater than one, +else it would make it impossible to evacuate a node. See [gh issue #7127](https://github.com/helm/charts/issues/7127) for more info. + +### Prometheus Metrics + +The Nginx ingress controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. + +You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. +Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) + +### ingress-nginx nginx\_status page/stats server + +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in nginx ingress controller: + +- In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed +- In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. + You can use `curl --unix-socket /tmp/nginx-status-server.sock http://localhost/nginx_status` inside the controller container to access it locally, or use the snippet from [nginx-ingress changelog](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230) to re-enable the http server + +### ExternalDNS Service Configuration + +Add an [ExternalDNS](https://github.com/kubernetes-incubator/external-dns) annotation to the LoadBalancer service: + +```yaml +controller: + service: + annotations: + external-dns.alpha.kubernetes.io/hostname: kubernetes-example.com. +``` + +### AWS L7 ELB with SSL Termination + +Annotate the controller as shown in the [nginx-ingress l7 patch](https://github.com/kubernetes/ingress-nginx/blob/ab3a789caae65eec4ad6e3b46b19750b481b6bce/deploy/aws/l7/service-l7.yaml): + +```yaml +controller: + service: + targetPorts: + http: http + https: http + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:XX-XXXX-X:XXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' +``` + +### AWS route53-mapper + +To configure the LoadBalancer service with the [route53-mapper addon](https://github.com/kubernetes/kops/blob/be63d4f1a7a46daaf1c4c482527328236850f111/addons/route53-mapper/README.md), add the `domainName` annotation and `dns` label: + +```yaml +controller: + service: + labels: + dns: "route53" + annotations: + domainName: "kubernetes-example.com" +``` + +### Additional Internal Load Balancer + +This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. + +By default, the ingress object will point to the external load balancer address, but if correctly configured, you can make use of the internal one if the URL you are looking up resolves to the internal load balancer's URL. + +You'll need to set both the following values: + +`controller.service.internal.enabled` +`controller.service.internal.annotations` + +If one of them is missing the internal load balancer will not be deployed. Example you may have `controller.service.internal.enabled=true` but no annotations set, in this case no action will be taken. + +`controller.service.internal.annotations` varies with the cloud service you're using. + +Example for AWS: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal ELB + service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for GCE: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal LB. More informations: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing + # For GKE versions 1.17 and later + networking.gke.io/load-balancer-type: "Internal" + # For earlier versions + # cloud.google.com/load-balancer-type: "Internal" + + # Any other annotation can be declared here. +``` + +Example for Azure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for Oracle Cloud Infrastructure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/oci-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +An use case for this scenario is having a split-view DNS setup where the public zone CNAME records point to the external balancer URL while the private zone CNAME records point to the internal balancer URL. This way, you only need one ingress kubernetes object. + +Optionally you can set `controller.service.loadBalancerIP` if you need a static IP for the resulting `LoadBalancer`. + +### Ingress Admission Webhooks + +With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +**This feature is enabled by default since 0.31.0.** + +With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) + +### Helm Error When Upgrading: spec.clusterIP: Invalid value: "" + +If you are upgrading this chart from a version between 0.31.0 and 1.2.2 then you may get an error like this: + +```console +Error: UPGRADE FAILED: Service "?????-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable +``` + +Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13646) but to resolve this you can set `xxxx.service.omitClusterIP` to `true` where `xxxx` is the service referenced in the error. + +As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. + +## Requirements + +Kubernetes: `>=1.19.0-0` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| commonLabels | object | `{}` | | +| controller.addHeaders | object | `{}` | Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers | +| controller.admissionWebhooks.annotations | object | `{}` | | +| controller.admissionWebhooks.certificate | string | `"/usr/local/certificates/cert"` | | +| controller.admissionWebhooks.createSecretJob.resources | object | `{}` | | +| controller.admissionWebhooks.enabled | bool | `true` | | +| controller.admissionWebhooks.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| controller.admissionWebhooks.failurePolicy | string | `"Fail"` | | +| controller.admissionWebhooks.key | string | `"/usr/local/certificates/key"` | | +| controller.admissionWebhooks.labels | object | `{}` | Labels to be added to admission webhooks | +| controller.admissionWebhooks.namespaceSelector | object | `{}` | | +| controller.admissionWebhooks.objectSelector | object | `{}` | | +| controller.admissionWebhooks.patch.enabled | bool | `true` | | +| controller.admissionWebhooks.patch.fsGroup | int | `2000` | | +| controller.admissionWebhooks.patch.image.digest | string | `"sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660"` | | +| controller.admissionWebhooks.patch.image.image | string | `"ingress-nginx/kube-webhook-certgen"` | | +| controller.admissionWebhooks.patch.image.pullPolicy | string | `"IfNotPresent"` | | +| controller.admissionWebhooks.patch.image.registry | string | `"registry.k8s.io"` | | +| controller.admissionWebhooks.patch.image.tag | string | `"v1.1.1"` | | +| controller.admissionWebhooks.patch.labels | object | `{}` | Labels to be added to patch job resources | +| controller.admissionWebhooks.patch.nodeSelector."kubernetes.io/os" | string | `"linux"` | | +| controller.admissionWebhooks.patch.podAnnotations | object | `{}` | | +| controller.admissionWebhooks.patch.priorityClassName | string | `""` | Provide a priority class name to the webhook patching job | +| controller.admissionWebhooks.patch.runAsUser | int | `2000` | | +| controller.admissionWebhooks.patch.tolerations | list | `[]` | | +| controller.admissionWebhooks.patchWebhookJob.resources | object | `{}` | | +| controller.admissionWebhooks.port | int | `8443` | | +| controller.admissionWebhooks.service.annotations | object | `{}` | | +| controller.admissionWebhooks.service.externalIPs | list | `[]` | | +| controller.admissionWebhooks.service.loadBalancerSourceRanges | list | `[]` | | +| controller.admissionWebhooks.service.servicePort | int | `443` | | +| controller.admissionWebhooks.service.type | string | `"ClusterIP"` | | +| controller.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes | +| controller.allowSnippetAnnotations | bool | `true` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected | +| controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet | +| controller.autoscaling.behavior | object | `{}` | | +| controller.autoscaling.enabled | bool | `false` | | +| controller.autoscaling.maxReplicas | int | `11` | | +| controller.autoscaling.minReplicas | int | `1` | | +| controller.autoscaling.targetCPUUtilizationPercentage | int | `50` | | +| controller.autoscaling.targetMemoryUtilizationPercentage | int | `50` | | +| controller.autoscalingTemplate | list | `[]` | | +| controller.config | object | `{}` | Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ | +| controller.configAnnotations | object | `{}` | Annotations to be added to the controller config configuration configmap. | +| controller.configMapNamespace | string | `""` | Allows customization of the configmap / nginx-configmap namespace; defaults to $(POD_NAMESPACE) | +| controller.containerName | string | `"controller"` | Configures the controller container name | +| controller.containerPort | object | `{"http":80,"https":443}` | Configures the ports that the nginx-controller listens on | +| controller.customTemplate.configMapKey | string | `""` | | +| controller.customTemplate.configMapName | string | `""` | | +| controller.dnsConfig | object | `{}` | Optionally customize the pod dnsConfig. | +| controller.dnsPolicy | string | `"ClusterFirst"` | Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. | +| controller.electionID | string | `"ingress-controller-leader"` | Election ID to use for status update | +| controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. | +| controller.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| controller.extraArgs | object | `{}` | Additional command line arguments to pass to nginx-ingress-controller E.g. to specify the default SSL certificate you can use | +| controller.extraContainers | list | `[]` | Additional containers to be added to the controller pod. See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. | +| controller.extraEnvs | list | `[]` | Additional environment variables to set | +| controller.extraInitContainers | list | `[]` | Containers, which are run before the app containers are started. | +| controller.extraModules | list | `[]` | | +| controller.extraVolumeMounts | list | `[]` | Additional volumeMounts to the controller main container. | +| controller.extraVolumes | list | `[]` | Additional volumes to the controller pod. | +| controller.healthCheckHost | string | `""` | Address to bind the health check endpoint. It is better to set this option to the internal node address if the ingress nginx controller is running in the `hostNetwork: true` mode. | +| controller.healthCheckPath | string | `"/healthz"` | Path of the health check endpoint. All requests received on the port defined by the healthz-port parameter are forwarded internally to this path. | +| controller.hostNetwork | bool | `false` | Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 is merged | +| controller.hostPort.enabled | bool | `false` | Enable 'hostPort' or not | +| controller.hostPort.ports.http | int | `80` | 'hostPort' http port | +| controller.hostPort.ports.https | int | `443` | 'hostPort' https port | +| controller.hostname | object | `{}` | Optionally customize the pod hostname. | +| controller.image.allowPrivilegeEscalation | bool | `true` | | +| controller.image.chroot | bool | `false` | | +| controller.image.digest | string | `"sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8"` | | +| controller.image.digestChroot | string | `"sha256:d301551cf62bc3fb75c69fa56f7aa1d9e87b5079333adaf38afe84d9b7439355"` | | +| controller.image.image | string | `"ingress-nginx/controller"` | | +| controller.image.pullPolicy | string | `"IfNotPresent"` | | +| controller.image.registry | string | `"registry.k8s.io"` | | +| controller.image.runAsUser | int | `101` | | +| controller.image.tag | string | `"v1.2.1"` | | +| controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation | +| controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). | +| controller.ingressClassResource.controllerValue | string | `"k8s.io/ingress-nginx"` | Controller-value of the controller that is processing this ingressClass | +| controller.ingressClassResource.default | bool | `false` | Is this the default ingressClass for the cluster | +| controller.ingressClassResource.enabled | bool | `true` | Is this ingressClass enabled or not | +| controller.ingressClassResource.name | string | `"nginx"` | Name of the ingressClass | +| controller.ingressClassResource.parameters | object | `{}` | Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters. | +| controller.keda.apiVersion | string | `"keda.sh/v1alpha1"` | | +| controller.keda.behavior | object | `{}` | | +| controller.keda.cooldownPeriod | int | `300` | | +| controller.keda.enabled | bool | `false` | | +| controller.keda.maxReplicas | int | `11` | | +| controller.keda.minReplicas | int | `1` | | +| controller.keda.pollingInterval | int | `30` | | +| controller.keda.restoreToOriginalReplicaCount | bool | `false` | | +| controller.keda.scaledObject.annotations | object | `{}` | | +| controller.keda.triggers | list | `[]` | | +| controller.kind | string | `"Deployment"` | Use a `DaemonSet` or `Deployment` | +| controller.labels | object | `{}` | Labels to be added to the controller Deployment or DaemonSet and other resources that do not have option to specify labels | +| controller.lifecycle | object | `{"preStop":{"exec":{"command":["/wait-shutdown"]}}}` | Improve connection draining when ingress controller pod is deleted using a lifecycle hook: With this new hook, we increased the default terminationGracePeriodSeconds from 30 seconds to 300, allowing the draining of connections up to five minutes. If the active connections end before that, the pod will terminate gracefully at that time. To effectively take advantage of this feature, the Configmap feature worker-shutdown-timeout new value is 240s instead of 10s. | +| controller.livenessProbe.failureThreshold | int | `5` | | +| controller.livenessProbe.httpGet.path | string | `"/healthz"` | | +| controller.livenessProbe.httpGet.port | int | `10254` | | +| controller.livenessProbe.httpGet.scheme | string | `"HTTP"` | | +| controller.livenessProbe.initialDelaySeconds | int | `10` | | +| controller.livenessProbe.periodSeconds | int | `10` | | +| controller.livenessProbe.successThreshold | int | `1` | | +| controller.livenessProbe.timeoutSeconds | int | `1` | | +| controller.maxmindLicenseKey | string | `""` | Maxmind license key to download GeoLite2 Databases. | +| controller.metrics.enabled | bool | `false` | | +| controller.metrics.port | int | `10254` | | +| controller.metrics.prometheusRule.additionalLabels | object | `{}` | | +| controller.metrics.prometheusRule.enabled | bool | `false` | | +| controller.metrics.prometheusRule.rules | list | `[]` | | +| controller.metrics.service.annotations | object | `{}` | | +| controller.metrics.service.externalIPs | list | `[]` | List of IP addresses at which the stats-exporter service is available | +| controller.metrics.service.loadBalancerSourceRanges | list | `[]` | | +| controller.metrics.service.servicePort | int | `10254` | | +| controller.metrics.service.type | string | `"ClusterIP"` | | +| controller.metrics.serviceMonitor.additionalLabels | object | `{}` | | +| controller.metrics.serviceMonitor.enabled | bool | `false` | | +| controller.metrics.serviceMonitor.metricRelabelings | list | `[]` | | +| controller.metrics.serviceMonitor.namespace | string | `""` | | +| controller.metrics.serviceMonitor.namespaceSelector | object | `{}` | | +| controller.metrics.serviceMonitor.relabelings | list | `[]` | | +| controller.metrics.serviceMonitor.scrapeInterval | string | `"30s"` | | +| controller.metrics.serviceMonitor.targetLabels | list | `[]` | | +| controller.minAvailable | int | `1` | | +| controller.minReadySeconds | int | `0` | `minReadySeconds` to avoid killing pods before we are ready | +| controller.name | string | `"controller"` | | +| controller.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for controller pod assignment | +| controller.podAnnotations | object | `{}` | Annotations to be added to controller pods | +| controller.podLabels | object | `{}` | Labels to add to the pod container metadata | +| controller.podSecurityContext | object | `{}` | Security Context policies for controller pods | +| controller.priorityClassName | string | `""` | | +| controller.proxySetHeaders | object | `{}` | Will add custom headers before sending traffic to backends according to https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/custom-headers | +| controller.publishService | object | `{"enabled":true,"pathOverride":""}` | Allows customization of the source of the IP address or FQDN to report in the ingress status field. By default, it reads the information provided by the service. If disable, the status field reports the IP address of the node or nodes where an ingress controller pod is running. | +| controller.publishService.enabled | bool | `true` | Enable 'publishService' or not | +| controller.publishService.pathOverride | string | `""` | Allows overriding of the publish service to bind to Must be / | +| controller.readinessProbe.failureThreshold | int | `3` | | +| controller.readinessProbe.httpGet.path | string | `"/healthz"` | | +| controller.readinessProbe.httpGet.port | int | `10254` | | +| controller.readinessProbe.httpGet.scheme | string | `"HTTP"` | | +| controller.readinessProbe.initialDelaySeconds | int | `10` | | +| controller.readinessProbe.periodSeconds | int | `10` | | +| controller.readinessProbe.successThreshold | int | `1` | | +| controller.readinessProbe.timeoutSeconds | int | `1` | | +| controller.replicaCount | int | `1` | | +| controller.reportNodeInternalIp | bool | `false` | Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network Ingress status was blank because there is no Service exposing the NGINX Ingress controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply | +| controller.resources.requests.cpu | string | `"100m"` | | +| controller.resources.requests.memory | string | `"90Mi"` | | +| controller.scope.enabled | bool | `false` | Enable 'scope' or not | +| controller.scope.namespace | string | `""` | Namespace to limit the controller to; defaults to $(POD_NAMESPACE) | +| controller.scope.namespaceSelector | string | `""` | When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. | +| controller.service.annotations | object | `{}` | | +| controller.service.appProtocol | bool | `true` | If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http It allows choosing the protocol for each backend specified in the Kubernetes service. See the following GitHub issue for more details about the purpose: https://github.com/kubernetes/kubernetes/issues/40244 Will be ignored for Kubernetes versions older than 1.20 | +| controller.service.enableHttp | bool | `true` | | +| controller.service.enableHttps | bool | `true` | | +| controller.service.enabled | bool | `true` | | +| controller.service.external.enabled | bool | `true` | | +| controller.service.externalIPs | list | `[]` | List of IP addresses at which the controller services are available | +| controller.service.internal.annotations | object | `{}` | Annotations are mandatory for the load balancer to come up. Varies with the cloud service. | +| controller.service.internal.enabled | bool | `false` | Enables an additional internal load balancer (besides the external one). | +| controller.service.internal.loadBalancerSourceRanges | list | `[]` | Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. | +| controller.service.ipFamilies | list | `["IPv4"]` | List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. | +| controller.service.ipFamilyPolicy | string | `"SingleStack"` | Represents the dual-stack-ness requested or required by this Service. Possible values are SingleStack, PreferDualStack or RequireDualStack. The ipFamilies and clusterIPs fields depend on the value of this field. | +| controller.service.labels | object | `{}` | | +| controller.service.loadBalancerIP | string | `""` | Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer | +| controller.service.loadBalancerSourceRanges | list | `[]` | | +| controller.service.nodePorts.http | string | `""` | | +| controller.service.nodePorts.https | string | `""` | | +| controller.service.nodePorts.tcp | object | `{}` | | +| controller.service.nodePorts.udp | object | `{}` | | +| controller.service.ports.http | int | `80` | | +| controller.service.ports.https | int | `443` | | +| controller.service.targetPorts.http | string | `"http"` | | +| controller.service.targetPorts.https | string | `"https"` | | +| controller.service.type | string | `"LoadBalancer"` | | +| controller.shareProcessNamespace | bool | `false` | | +| controller.sysctls | object | `{}` | See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls | +| controller.tcp.annotations | object | `{}` | Annotations to be added to the tcp config configmap | +| controller.tcp.configMapNamespace | string | `""` | Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE) | +| controller.terminationGracePeriodSeconds | int | `300` | `terminationGracePeriodSeconds` to avoid killing pods before we are ready | +| controller.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints | +| controller.topologySpreadConstraints | list | `[]` | Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. | +| controller.udp.annotations | object | `{}` | Annotations to be added to the udp config configmap | +| controller.udp.configMapNamespace | string | `""` | Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) | +| controller.updateStrategy | object | `{}` | The update strategy to apply to the Deployment or DaemonSet | +| controller.watchIngressWithoutClass | bool | `false` | Process Ingress objects without ingressClass annotation/ingressClassName field Overrides value for --watch-ingress-without-class flag of the controller binary Defaults to false | +| defaultBackend.affinity | object | `{}` | | +| defaultBackend.autoscaling.annotations | object | `{}` | | +| defaultBackend.autoscaling.enabled | bool | `false` | | +| defaultBackend.autoscaling.maxReplicas | int | `2` | | +| defaultBackend.autoscaling.minReplicas | int | `1` | | +| defaultBackend.autoscaling.targetCPUUtilizationPercentage | int | `50` | | +| defaultBackend.autoscaling.targetMemoryUtilizationPercentage | int | `50` | | +| defaultBackend.containerSecurityContext | object | `{}` | Security Context policies for controller main container. See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls | +| defaultBackend.enabled | bool | `false` | | +| defaultBackend.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| defaultBackend.extraArgs | object | `{}` | | +| defaultBackend.extraEnvs | list | `[]` | Additional environment variables to set for defaultBackend pods | +| defaultBackend.extraVolumeMounts | list | `[]` | | +| defaultBackend.extraVolumes | list | `[]` | | +| defaultBackend.image.allowPrivilegeEscalation | bool | `false` | | +| defaultBackend.image.image | string | `"defaultbackend-amd64"` | | +| defaultBackend.image.pullPolicy | string | `"IfNotPresent"` | | +| defaultBackend.image.readOnlyRootFilesystem | bool | `true` | | +| defaultBackend.image.registry | string | `"registry.k8s.io"` | | +| defaultBackend.image.runAsNonRoot | bool | `true` | | +| defaultBackend.image.runAsUser | int | `65534` | | +| defaultBackend.image.tag | string | `"1.5"` | | +| defaultBackend.labels | object | `{}` | Labels to be added to the default backend resources | +| defaultBackend.livenessProbe.failureThreshold | int | `3` | | +| defaultBackend.livenessProbe.initialDelaySeconds | int | `30` | | +| defaultBackend.livenessProbe.periodSeconds | int | `10` | | +| defaultBackend.livenessProbe.successThreshold | int | `1` | | +| defaultBackend.livenessProbe.timeoutSeconds | int | `5` | | +| defaultBackend.minAvailable | int | `1` | | +| defaultBackend.name | string | `"defaultbackend"` | | +| defaultBackend.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for default backend pod assignment | +| defaultBackend.podAnnotations | object | `{}` | Annotations to be added to default backend pods | +| defaultBackend.podLabels | object | `{}` | Labels to add to the pod container metadata | +| defaultBackend.podSecurityContext | object | `{}` | Security Context policies for controller pods See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls | +| defaultBackend.port | int | `8080` | | +| defaultBackend.priorityClassName | string | `""` | | +| defaultBackend.readinessProbe.failureThreshold | int | `6` | | +| defaultBackend.readinessProbe.initialDelaySeconds | int | `0` | | +| defaultBackend.readinessProbe.periodSeconds | int | `5` | | +| defaultBackend.readinessProbe.successThreshold | int | `1` | | +| defaultBackend.readinessProbe.timeoutSeconds | int | `5` | | +| defaultBackend.replicaCount | int | `1` | | +| defaultBackend.resources | object | `{}` | | +| defaultBackend.service.annotations | object | `{}` | | +| defaultBackend.service.externalIPs | list | `[]` | List of IP addresses at which the default backend service is available | +| defaultBackend.service.loadBalancerSourceRanges | list | `[]` | | +| defaultBackend.service.servicePort | int | `80` | | +| defaultBackend.service.type | string | `"ClusterIP"` | | +| defaultBackend.serviceAccount.automountServiceAccountToken | bool | `true` | | +| defaultBackend.serviceAccount.create | bool | `true` | | +| defaultBackend.serviceAccount.name | string | `""` | | +| defaultBackend.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints | +| dhParam | string | `nil` | A base64-encoded Diffie-Hellman parameter. This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` | +| imagePullSecrets | list | `[]` | Optional array of imagePullSecrets containing private registry credentials | +| podSecurityPolicy.enabled | bool | `false` | | +| portNamePrefix | string | `""` | Prefix for TCP and UDP ports names in ingress controller service | +| rbac.create | bool | `true` | | +| rbac.scope | bool | `false` | | +| revisionHistoryLimit | int | `10` | Rollback limit | +| serviceAccount.annotations | object | `{}` | Annotations for the controller service account | +| serviceAccount.automountServiceAccountToken | bool | `true` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| tcp | object | `{}` | TCP service key-value pairs | +| udp | object | `{}` | UDP service key-value pairs | + diff --git a/nginx-ingress/README.md.gotmpl b/nginx-ingress/README.md.gotmpl new file mode 100644 index 0000000..8959961 --- /dev/null +++ b/nginx-ingress/README.md.gotmpl @@ -0,0 +1,235 @@ +{{ template "chart.header" . }} +[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources. + +This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Chart version 3.x.x: Kubernetes v1.16+ +- Chart version 4.x.x and above: Kubernetes v1.19+ + +## Get Repo Info + +```console +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +``` + +## Install Chart + +**Important:** only helm3 is supported + +```console +helm install [RELEASE_NAME] ingress-nginx/ingress-nginx +``` + +The command deploys ingress-nginx on the Kubernetes cluster in the default configuration. + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading With Zero Downtime in Production + +By default the ingress-nginx controller has service interruptions whenever it's pods are restarted or redeployed. In order to fix that, see the excellent blog post by Lindsay Landry from Codecademy: [Kubernetes: Nginx and Zero Downtime in Production](https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8). + +### Migrating from stable/nginx-ingress + +There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: + +1. For Nginx Ingress controllers used for non-critical services, the easiest method is to [uninstall](#uninstall-chart) the old release and [install](#install-chart) the new one +1. For critical services in production that require zero-downtime, you will want to: + 1. [Install](#install-chart) a second Ingress controller + 1. Redirect your DNS traffic from the old controller to the new controller + 1. Log traffic from both controllers during this changeover + 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it + 1. For details on all of these steps see [Upgrading With Zero Downtime in Production](#upgrading-with-zero-downtime-in-production) + +Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values ingress-nginx/ingress-nginx +``` + +### PodDisruptionBudget + +Note that the PodDisruptionBudget resource will only be defined if the replicaCount is greater than one, +else it would make it impossible to evacuate a node. See [gh issue #7127](https://github.com/helm/charts/issues/7127) for more info. + +### Prometheus Metrics + +The Nginx ingress controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. + +You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. +Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) + +### ingress-nginx nginx\_status page/stats server + +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in nginx ingress controller: + +- In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed +- In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. + You can use `curl --unix-socket /tmp/nginx-status-server.sock http://localhost/nginx_status` inside the controller container to access it locally, or use the snippet from [nginx-ingress changelog](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230) to re-enable the http server + +### ExternalDNS Service Configuration + +Add an [ExternalDNS](https://github.com/kubernetes-incubator/external-dns) annotation to the LoadBalancer service: + +```yaml +controller: + service: + annotations: + external-dns.alpha.kubernetes.io/hostname: kubernetes-example.com. +``` + +### AWS L7 ELB with SSL Termination + +Annotate the controller as shown in the [nginx-ingress l7 patch](https://github.com/kubernetes/ingress-nginx/blob/ab3a789caae65eec4ad6e3b46b19750b481b6bce/deploy/aws/l7/service-l7.yaml): + +```yaml +controller: + service: + targetPorts: + http: http + https: http + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:XX-XXXX-X:XXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' +``` + +### AWS route53-mapper + +To configure the LoadBalancer service with the [route53-mapper addon](https://github.com/kubernetes/kops/blob/be63d4f1a7a46daaf1c4c482527328236850f111/addons/route53-mapper/README.md), add the `domainName` annotation and `dns` label: + +```yaml +controller: + service: + labels: + dns: "route53" + annotations: + domainName: "kubernetes-example.com" +``` + +### Additional Internal Load Balancer + +This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. + +By default, the ingress object will point to the external load balancer address, but if correctly configured, you can make use of the internal one if the URL you are looking up resolves to the internal load balancer's URL. + +You'll need to set both the following values: + +`controller.service.internal.enabled` +`controller.service.internal.annotations` + +If one of them is missing the internal load balancer will not be deployed. Example you may have `controller.service.internal.enabled=true` but no annotations set, in this case no action will be taken. + +`controller.service.internal.annotations` varies with the cloud service you're using. + +Example for AWS: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal ELB + service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for GCE: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal LB. More informations: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing + # For GKE versions 1.17 and later + networking.gke.io/load-balancer-type: "Internal" + # For earlier versions + # cloud.google.com/load-balancer-type: "Internal" + + # Any other annotation can be declared here. +``` + +Example for Azure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for Oracle Cloud Infrastructure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/oci-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +An use case for this scenario is having a split-view DNS setup where the public zone CNAME records point to the external balancer URL while the private zone CNAME records point to the internal balancer URL. This way, you only need one ingress kubernetes object. + +Optionally you can set `controller.service.loadBalancerIP` if you need a static IP for the resulting `LoadBalancer`. + +### Ingress Admission Webhooks + +With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +**This feature is enabled by default since 0.31.0.** + +With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) + +### Helm Error When Upgrading: spec.clusterIP: Invalid value: "" + +If you are upgrading this chart from a version between 0.31.0 and 1.2.2 then you may get an error like this: + +```console +Error: UPGRADE FAILED: Service "?????-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable +``` + +Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13646) but to resolve this you can set `xxxx.service.omitClusterIP` to `true` where `xxxx` is the service referenced in the error. + +As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/nginx-ingress/ci/controller-custom-ingressclass-flags.yaml b/nginx-ingress/ci/controller-custom-ingressclass-flags.yaml new file mode 100644 index 0000000..b28a232 --- /dev/null +++ b/nginx-ingress/ci/controller-custom-ingressclass-flags.yaml @@ -0,0 +1,7 @@ +controller: + watchIngressWithoutClass: true + ingressClassResource: + name: custom-nginx + enabled: true + default: true + controllerValue: "k8s.io/custom-nginx" diff --git a/nginx-ingress/ci/daemonset-customconfig-values.yaml b/nginx-ingress/ci/daemonset-customconfig-values.yaml new file mode 100644 index 0000000..4393a5b --- /dev/null +++ b/nginx-ingress/ci/daemonset-customconfig-values.yaml @@ -0,0 +1,14 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + kind: DaemonSet + allowSnippetAnnotations: false + admissionWebhooks: + enabled: false + service: + type: ClusterIP + + config: + use-proxy-protocol: "true" diff --git a/nginx-ingress/ci/daemonset-customnodeport-values.yaml b/nginx-ingress/ci/daemonset-customnodeport-values.yaml new file mode 100644 index 0000000..1d94be2 --- /dev/null +++ b/nginx-ingress/ci/daemonset-customnodeport-values.yaml @@ -0,0 +1,22 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + + service: + type: NodePort + nodePorts: + tcp: + 9000: 30090 + udp: + 9001: 30091 + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/daemonset-extra-modules.yaml b/nginx-ingress/ci/daemonset-extra-modules.yaml new file mode 100644 index 0000000..f299dbf --- /dev/null +++ b/nginx-ingress/ci/daemonset-extra-modules.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + service: + type: ClusterIP + extraModules: + - name: opentelemetry + image: busybox diff --git a/nginx-ingress/ci/daemonset-headers-values.yaml b/nginx-ingress/ci/daemonset-headers-values.yaml new file mode 100644 index 0000000..ab7d47b --- /dev/null +++ b/nginx-ingress/ci/daemonset-headers-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + addHeaders: + X-Frame-Options: deny + proxySetHeaders: + X-Forwarded-Proto: https + service: + type: ClusterIP diff --git a/nginx-ingress/ci/daemonset-internal-lb-values.yaml b/nginx-ingress/ci/daemonset-internal-lb-values.yaml new file mode 100644 index 0000000..0a200a7 --- /dev/null +++ b/nginx-ingress/ci/daemonset-internal-lb-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + internal: + enabled: true + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: "true" diff --git a/nginx-ingress/ci/daemonset-nodeport-values.yaml b/nginx-ingress/ci/daemonset-nodeport-values.yaml new file mode 100644 index 0000000..3b7aa2f --- /dev/null +++ b/nginx-ingress/ci/daemonset-nodeport-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort diff --git a/nginx-ingress/ci/daemonset-podannotations-values.yaml b/nginx-ingress/ci/daemonset-podannotations-values.yaml new file mode 100644 index 0000000..0b55306 --- /dev/null +++ b/nginx-ingress/ci/daemonset-podannotations-values.yaml @@ -0,0 +1,17 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP + podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scheme: http + prometheus.io/scrape: "true" diff --git a/nginx-ingress/ci/daemonset-tcp-udp-configMapNamespace-values.yaml b/nginx-ingress/ci/daemonset-tcp-udp-configMapNamespace-values.yaml new file mode 100644 index 0000000..acd86a7 --- /dev/null +++ b/nginx-ingress/ci/daemonset-tcp-udp-configMapNamespace-values.yaml @@ -0,0 +1,20 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + tcp: + configMapNamespace: default + udp: + configMapNamespace: default + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/daemonset-tcp-udp-portNamePrefix-values.yaml b/nginx-ingress/ci/daemonset-tcp-udp-portNamePrefix-values.yaml new file mode 100644 index 0000000..90b0f57 --- /dev/null +++ b/nginx-ingress/ci/daemonset-tcp-udp-portNamePrefix-values.yaml @@ -0,0 +1,18 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" + +portNamePrefix: "port" diff --git a/nginx-ingress/ci/daemonset-tcp-udp-values.yaml b/nginx-ingress/ci/daemonset-tcp-udp-values.yaml new file mode 100644 index 0000000..25ee64d --- /dev/null +++ b/nginx-ingress/ci/daemonset-tcp-udp-values.yaml @@ -0,0 +1,16 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/daemonset-tcp-values.yaml b/nginx-ingress/ci/daemonset-tcp-values.yaml new file mode 100644 index 0000000..380c8b4 --- /dev/null +++ b/nginx-ingress/ci/daemonset-tcp-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/deamonset-default-values.yaml b/nginx-ingress/ci/deamonset-default-values.yaml new file mode 100644 index 0000000..82fa23e --- /dev/null +++ b/nginx-ingress/ci/deamonset-default-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deamonset-metrics-values.yaml b/nginx-ingress/ci/deamonset-metrics-values.yaml new file mode 100644 index 0000000..cb3cb54 --- /dev/null +++ b/nginx-ingress/ci/deamonset-metrics-values.yaml @@ -0,0 +1,12 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deamonset-psp-values.yaml b/nginx-ingress/ci/deamonset-psp-values.yaml new file mode 100644 index 0000000..8026a63 --- /dev/null +++ b/nginx-ingress/ci/deamonset-psp-values.yaml @@ -0,0 +1,13 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/nginx-ingress/ci/deamonset-webhook-and-psp-values.yaml b/nginx-ingress/ci/deamonset-webhook-and-psp-values.yaml new file mode 100644 index 0000000..fccdb13 --- /dev/null +++ b/nginx-ingress/ci/deamonset-webhook-and-psp-values.yaml @@ -0,0 +1,13 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/nginx-ingress/ci/deamonset-webhook-values.yaml b/nginx-ingress/ci/deamonset-webhook-values.yaml new file mode 100644 index 0000000..54d364d --- /dev/null +++ b/nginx-ingress/ci/deamonset-webhook-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-autoscaling-behavior-values.yaml b/nginx-ingress/ci/deployment-autoscaling-behavior-values.yaml new file mode 100644 index 0000000..dca3f35 --- /dev/null +++ b/nginx-ingress/ci/deployment-autoscaling-behavior-values.yaml @@ -0,0 +1,14 @@ +controller: + autoscaling: + enabled: true + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Pods + value: 1 + periodSeconds: 180 + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-autoscaling-values.yaml b/nginx-ingress/ci/deployment-autoscaling-values.yaml new file mode 100644 index 0000000..b8b3ac6 --- /dev/null +++ b/nginx-ingress/ci/deployment-autoscaling-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + autoscaling: + enabled: true + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-customconfig-values.yaml b/nginx-ingress/ci/deployment-customconfig-values.yaml new file mode 100644 index 0000000..1749418 --- /dev/null +++ b/nginx-ingress/ci/deployment-customconfig-values.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + config: + use-proxy-protocol: "true" + allowSnippetAnnotations: false + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-customnodeport-values.yaml b/nginx-ingress/ci/deployment-customnodeport-values.yaml new file mode 100644 index 0000000..a564eaf --- /dev/null +++ b/nginx-ingress/ci/deployment-customnodeport-values.yaml @@ -0,0 +1,20 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort + nodePorts: + tcp: + 9000: 30090 + udp: + 9001: 30091 + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/deployment-default-values.yaml b/nginx-ingress/ci/deployment-default-values.yaml new file mode 100644 index 0000000..9f46b4e --- /dev/null +++ b/nginx-ingress/ci/deployment-default-values.yaml @@ -0,0 +1,8 @@ +# Left blank to test default values +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-extra-modules.yaml b/nginx-ingress/ci/deployment-extra-modules.yaml new file mode 100644 index 0000000..ec59235 --- /dev/null +++ b/nginx-ingress/ci/deployment-extra-modules.yaml @@ -0,0 +1,10 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + extraModules: + - name: opentelemetry + image: busybox diff --git a/nginx-ingress/ci/deployment-headers-values.yaml b/nginx-ingress/ci/deployment-headers-values.yaml new file mode 100644 index 0000000..17a11ac --- /dev/null +++ b/nginx-ingress/ci/deployment-headers-values.yaml @@ -0,0 +1,13 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + addHeaders: + X-Frame-Options: deny + proxySetHeaders: + X-Forwarded-Proto: https + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-internal-lb-values.yaml b/nginx-ingress/ci/deployment-internal-lb-values.yaml new file mode 100644 index 0000000..fd8df8d --- /dev/null +++ b/nginx-ingress/ci/deployment-internal-lb-values.yaml @@ -0,0 +1,13 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + internal: + enabled: true + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: "true" diff --git a/nginx-ingress/ci/deployment-metrics-values.yaml b/nginx-ingress/ci/deployment-metrics-values.yaml new file mode 100644 index 0000000..9209ad5 --- /dev/null +++ b/nginx-ingress/ci/deployment-metrics-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP diff --git a/nginx-ingress/ci/deployment-nodeport-values.yaml b/nginx-ingress/ci/deployment-nodeport-values.yaml new file mode 100644 index 0000000..cd9b323 --- /dev/null +++ b/nginx-ingress/ci/deployment-nodeport-values.yaml @@ -0,0 +1,9 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort diff --git a/nginx-ingress/ci/deployment-podannotations-values.yaml b/nginx-ingress/ci/deployment-podannotations-values.yaml new file mode 100644 index 0000000..b48d93c --- /dev/null +++ b/nginx-ingress/ci/deployment-podannotations-values.yaml @@ -0,0 +1,16 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP + podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scheme: http + prometheus.io/scrape: "true" diff --git a/nginx-ingress/ci/deployment-psp-values.yaml b/nginx-ingress/ci/deployment-psp-values.yaml new file mode 100644 index 0000000..2f332a7 --- /dev/null +++ b/nginx-ingress/ci/deployment-psp-values.yaml @@ -0,0 +1,10 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/nginx-ingress/ci/deployment-tcp-udp-configMapNamespace-values.yaml b/nginx-ingress/ci/deployment-tcp-udp-configMapNamespace-values.yaml new file mode 100644 index 0000000..c51a4e9 --- /dev/null +++ b/nginx-ingress/ci/deployment-tcp-udp-configMapNamespace-values.yaml @@ -0,0 +1,19 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + tcp: + configMapNamespace: default + udp: + configMapNamespace: default + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/deployment-tcp-udp-portNamePrefix-values.yaml b/nginx-ingress/ci/deployment-tcp-udp-portNamePrefix-values.yaml new file mode 100644 index 0000000..56323c5 --- /dev/null +++ b/nginx-ingress/ci/deployment-tcp-udp-portNamePrefix-values.yaml @@ -0,0 +1,17 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" + +portNamePrefix: "port" diff --git a/nginx-ingress/ci/deployment-tcp-udp-values.yaml b/nginx-ingress/ci/deployment-tcp-udp-values.yaml new file mode 100644 index 0000000..5b45b69 --- /dev/null +++ b/nginx-ingress/ci/deployment-tcp-udp-values.yaml @@ -0,0 +1,15 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/deployment-tcp-values.yaml b/nginx-ingress/ci/deployment-tcp-values.yaml new file mode 100644 index 0000000..ac0b6e6 --- /dev/null +++ b/nginx-ingress/ci/deployment-tcp-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + 9001: "default/test:8080" diff --git a/nginx-ingress/ci/deployment-webhook-and-psp-values.yaml b/nginx-ingress/ci/deployment-webhook-and-psp-values.yaml new file mode 100644 index 0000000..6195bb3 --- /dev/null +++ b/nginx-ingress/ci/deployment-webhook-and-psp-values.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/nginx-ingress/ci/deployment-webhook-resources-values.yaml b/nginx-ingress/ci/deployment-webhook-resources-values.yaml new file mode 100644 index 0000000..49ebbb0 --- /dev/null +++ b/nginx-ingress/ci/deployment-webhook-resources-values.yaml @@ -0,0 +1,23 @@ +controller: + service: + type: ClusterIP + admissionWebhooks: + enabled: true + createSecretJob: + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi + patchWebhookJob: + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi + patch: + enabled: true diff --git a/nginx-ingress/ci/deployment-webhook-values.yaml b/nginx-ingress/ci/deployment-webhook-values.yaml new file mode 100644 index 0000000..76669a5 --- /dev/null +++ b/nginx-ingress/ci/deployment-webhook-values.yaml @@ -0,0 +1,9 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP diff --git a/nginx-ingress/templates/NOTES.txt b/nginx-ingress/templates/NOTES.txt new file mode 100644 index 0000000..8985c56 --- /dev/null +++ b/nginx-ingress/templates/NOTES.txt @@ -0,0 +1,80 @@ +The ingress-nginx controller has been installed. + +{{- if contains "NodePort" .Values.controller.service.type }} +Get the application URL by running these commands: + +{{- if (not (empty .Values.controller.service.nodePorts.http)) }} + export HTTP_NODE_PORT={{ .Values.controller.service.nodePorts.http }} +{{- else }} + export HTTP_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[0].nodePort}" {{ include "ingress-nginx.controller.fullname" . }}) +{{- end }} +{{- if (not (empty .Values.controller.service.nodePorts.https)) }} + export HTTPS_NODE_PORT={{ .Values.controller.service.nodePorts.https }} +{{- else }} + export HTTPS_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[1].nodePort}" {{ include "ingress-nginx.controller.fullname" . }}) +{{- end }} + export NODE_IP=$(kubectl --namespace {{ .Release.Namespace }} get nodes -o jsonpath="{.items[0].status.addresses[1].address}") + + echo "Visit http://$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP." + echo "Visit https://$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS." +{{- else if contains "LoadBalancer" .Values.controller.service.type }} +It may take a few minutes for the LoadBalancer IP to be available. +You can watch the status by running 'kubectl --namespace {{ .Release.Namespace }} get services -o wide -w {{ include "ingress-nginx.controller.fullname" . }}' +{{- else if contains "ClusterIP" .Values.controller.service.type }} +Get the application URL by running these commands: + export POD_NAME=$(kubectl --namespace {{ .Release.Namespace }} get pods -o jsonpath="{.items[0].metadata.name}" -l "app={{ template "ingress-nginx.name" . }},component={{ .Values.controller.name }},release={{ .Release.Name }}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 + echo "Visit http://127.0.0.1:8080 to access your application." +{{- end }} + +An example Ingress that makes use of the controller: + +{{- $isV1 := semverCompare ">=1" .Chart.AppVersion}} + apiVersion: networking.k8s.io/v1 + kind: Ingress + metadata: + name: example + namespace: foo + {{- if eq $isV1 false }} + annotations: + kubernetes.io/ingress.class: {{ .Values.controller.ingressClass }} + {{- end }} + spec: + {{- if $isV1 }} + ingressClassName: {{ .Values.controller.ingressClassResource.name }} + {{- end }} + rules: + - host: www.example.com + http: + paths: + - pathType: Prefix + backend: + service: + name: exampleService + port: + number: 80 + path: / + # This section is only required if TLS is to be enabled for the Ingress + tls: + - hosts: + - www.example.com + secretName: example-tls + +If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided: + + apiVersion: v1 + kind: Secret + metadata: + name: example-tls + namespace: foo + data: + tls.crt: + tls.key: + type: kubernetes.io/tls + +{{- if .Values.controller.headers }} +################################################################################# +###### WARNING: `controller.headers` has been deprecated! ##### +###### It has been renamed to `controller.proxySetHeaders`. ##### +################################################################################# +{{- end }} diff --git a/nginx-ingress/templates/_helpers.tpl b/nginx-ingress/templates/_helpers.tpl new file mode 100644 index 0000000..e69de0c --- /dev/null +++ b/nginx-ingress/templates/_helpers.tpl @@ -0,0 +1,185 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "ingress-nginx.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ingress-nginx.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | 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). +*/}} +{{- define "ingress-nginx.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 -}} + + +{{/* +Container SecurityContext. +*/}} +{{- define "controller.containerSecurityContext" -}} +{{- if .Values.controller.containerSecurityContext -}} +{{- toYaml .Values.controller.containerSecurityContext -}} +{{- else -}} +capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + {{- if .Values.controller.image.chroot }} + - SYS_CHROOT + {{- end }} +runAsUser: {{ .Values.controller.image.runAsUser }} +allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }} +{{- end }} +{{- end -}} + +{{/* +Get specific image +*/}} +{{- define "ingress-nginx.image" -}} +{{- if .chroot -}} +{{- printf "%s-chroot" .image -}} +{{- else -}} +{{- printf "%s" .image -}} +{{- end }} +{{- end -}} + +{{/* +Get specific image digest +*/}} +{{- define "ingress-nginx.imageDigest" -}} +{{- if .chroot -}} +{{- if .digestChroot -}} +{{- printf "@%s" .digestChroot -}} +{{- end }} +{{- else -}} +{{ if .digest -}} +{{- printf "@%s" .digest -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified controller name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ingress-nginx.controller.fullname" -}} +{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.controller.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Construct the path for the publish-service. + +By convention this will simply use the / to match the name of the +service generated. + +Users can provide an override for an explicit service they want bound via `.Values.controller.publishService.pathOverride` + +*/}} +{{- define "ingress-nginx.controller.publishServicePath" -}} +{{- $defServiceName := printf "%s/%s" "$(POD_NAMESPACE)" (include "ingress-nginx.controller.fullname" .) -}} +{{- $servicePath := default $defServiceName .Values.controller.publishService.pathOverride }} +{{- print $servicePath | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified default backend name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ingress-nginx.defaultBackend.fullname" -}} +{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.defaultBackend.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "ingress-nginx.labels" -}} +helm.sh/chart: {{ include "ingress-nginx.chart" . }} +{{ include "ingress-nginx.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/part-of: {{ template "ingress-nginx.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels}} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "ingress-nginx.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ingress-nginx.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "ingress-nginx.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "ingress-nginx.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the backend service account to use - only used when podsecuritypolicy is also enabled +*/}} +{{- define "ingress-nginx.defaultBackend.serviceAccountName" -}} +{{- if .Values.defaultBackend.serviceAccount.create -}} + {{ default (printf "%s-backend" (include "ingress-nginx.fullname" .)) .Values.defaultBackend.serviceAccount.name }} +{{- else -}} + {{ default "default-backend" .Values.defaultBackend.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiGroup for PodSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiGroup" -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy" -}} +{{- else -}} +{{- print "extensions" -}} +{{- end -}} +{{- end -}} + +{{/* +Check the ingress controller version tag is at most three versions behind the last release +*/}} +{{- define "isControllerTagValid" -}} +{{- if not (semverCompare ">=0.27.0-0" .Values.controller.image.tag) -}} +{{- fail "Controller container image tag should be 0.27.0 or higher" -}} +{{- end -}} +{{- end -}} + +{{/* +IngressClass parameters. +*/}} +{{- define "ingressClass.parameters" -}} + {{- if .Values.controller.ingressClassResource.parameters -}} + parameters: +{{ toYaml .Values.controller.ingressClassResource.parameters | indent 4}} + {{ end }} +{{- end -}} diff --git a/nginx-ingress/templates/_params.tpl b/nginx-ingress/templates/_params.tpl new file mode 100644 index 0000000..305ce0d --- /dev/null +++ b/nginx-ingress/templates/_params.tpl @@ -0,0 +1,62 @@ +{{- define "ingress-nginx.params" -}} +- /nginx-ingress-controller +{{- if .Values.defaultBackend.enabled }} +- --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }} +{{- end }} +{{- if and .Values.controller.publishService.enabled .Values.controller.service.enabled }} +{{- if .Values.controller.service.external.enabled }} +- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }} +{{- else if .Values.controller.service.internal.enabled }} +- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}-internal +{{- end }} +{{- end }} +- --election-id={{ .Values.controller.electionID }} +- --controller-class={{ .Values.controller.ingressClassResource.controllerValue }} +{{- if .Values.controller.ingressClass }} +- --ingress-class={{ .Values.controller.ingressClass }} +{{- end }} +- --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.tcp }} +- --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp +{{- end }} +{{- if .Values.udp }} +- --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp +{{- end }} +{{- if .Values.controller.scope.enabled }} +- --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }} +{{- end }} +{{- if and (not .Values.controller.scope.enabled) .Values.controller.scope.namespaceSelector }} +- --watch-namespace-selector={{ default "" .Values.controller.scope.namespaceSelector }} +{{- end }} +{{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }} +- --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.enabled }} +- --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }} +- --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }} +- --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }} +{{- end }} +{{- if .Values.controller.maxmindLicenseKey }} +- --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }} +{{- end }} +{{- if .Values.controller.healthCheckHost }} +- --healthz-host={{ .Values.controller.healthCheckHost }} +{{- end }} +{{- if not (eq .Values.controller.healthCheckPath "/healthz") }} +- --health-check-path={{ .Values.controller.healthCheckPath }} +{{- end }} +{{- if .Values.controller.ingressClassByName }} +- --ingress-class-by-name=true +{{- end }} +{{- if .Values.controller.watchIngressWithoutClass }} +- --watch-ingress-without-class=true +{{- end }} +{{- range $key, $value := .Values.controller.extraArgs }} +{{- /* Accept keys without values or with false as value */}} +{{- if eq ($value | quote | len) 2 }} +- --{{ $key }} +{{- else }} +- --{{ $key }}={{ $value }} +{{- end }} +{{- end }} +{{- end -}} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/clusterrole.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/clusterrole.yaml new file mode 100644 index 0000000..5659a1f --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/clusterrole.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + {{- with .Values.controller.admissionWebhooks.existingPsp }} + - {{ . }} + {{- else }} + - {{ include "ingress-nginx.fullname" . }}-admission + {{- end }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/clusterrolebinding.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/clusterrolebinding.yaml new file mode 100644 index 0000000..abf17fb --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/clusterrolebinding.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ingress-nginx.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/job-createSecret.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/job-createSecret.yaml new file mode 100644 index 0000000..f20e247 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/job-createSecret.yaml @@ -0,0 +1,76 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-create + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- with .Values.controller.admissionWebhooks.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 +{{- end }} + template: + metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-create + {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: create + {{- with .Values.controller.admissionWebhooks.patch.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }} + args: + - create + - --host={{ include "ingress-nginx.controller.fullname" . }}-admission,{{ include "ingress-nginx.controller.fullname" . }}-admission.$(POD_NAMESPACE).svc + - --namespace=$(POD_NAMESPACE) + - --secret-name={{ include "ingress-nginx.fullname" . }}-admission + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + securityContext: + allowPrivilegeEscalation: false + {{- if .Values.controller.admissionWebhooks.createSecretJob.resources }} + resources: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.resources | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.tolerations }} + tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }} + fsGroup: {{ .Values.controller.admissionWebhooks.patch.fsGroup }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/job-patchWebhook.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/job-patchWebhook.yaml new file mode 100644 index 0000000..8583685 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/job-patchWebhook.yaml @@ -0,0 +1,78 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-patch + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- with .Values.controller.admissionWebhooks.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 +{{- end }} + template: + metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-patch + {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: patch + {{- with .Values.controller.admissionWebhooks.patch.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }} + args: + - patch + - --webhook-name={{ include "ingress-nginx.fullname" . }}-admission + - --namespace=$(POD_NAMESPACE) + - --patch-mutating=false + - --secret-name={{ include "ingress-nginx.fullname" . }}-admission + - --patch-failure-policy={{ .Values.controller.admissionWebhooks.failurePolicy }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + securityContext: + allowPrivilegeEscalation: false + {{- if .Values.controller.admissionWebhooks.patchWebhookJob.resources }} + resources: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.resources | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.tolerations }} + tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }} + {{- end }} + securityContext: + runAsNonRoot: true + runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }} + fsGroup: {{ .Values.controller.admissionWebhooks.patch.fsGroup }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/psp.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/psp.yaml new file mode 100644 index 0000000..70edde3 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/psp.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled .Values.podSecurityPolicy.enabled (empty .Values.controller.admissionWebhooks.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: false + fsGroup: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + requiredDropCapabilities: + - ALL + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/role.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/role.yaml new file mode 100644 index 0000000..795bac6 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/role.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/rolebinding.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/rolebinding.yaml new file mode 100644 index 0000000..698c5c8 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/job-patch/serviceaccount.yaml b/nginx-ingress/templates/admission-webhooks/job-patch/serviceaccount.yaml new file mode 100644 index 0000000..eae4751 --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/job-patch/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/admission-webhooks/validating-webhook.yaml b/nginx-ingress/templates/admission-webhooks/validating-webhook.yaml new file mode 100644 index 0000000..8caffcb --- /dev/null +++ b/nginx-ingress/templates/admission-webhooks/validating-webhook.yaml @@ -0,0 +1,48 @@ +{{- if .Values.controller.admissionWebhooks.enabled -}} +# before changing this value, check the required kubernetes version +# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + {{- if .Values.controller.admissionWebhooks.annotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-admission +webhooks: + - name: validate.nginx.ingress.kubernetes.io + matchPolicy: Equivalent + rules: + - apiGroups: + - networking.k8s.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - ingresses + failurePolicy: {{ .Values.controller.admissionWebhooks.failurePolicy | default "Fail" }} + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + namespace: {{ .Release.Namespace | quote }} + name: {{ include "ingress-nginx.controller.fullname" . }}-admission + path: /networking/v1/ingresses + {{- if .Values.controller.admissionWebhooks.timeoutSeconds }} + timeoutSeconds: {{ .Values.controller.admissionWebhooks.timeoutSeconds }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.namespaceSelector }} + namespaceSelector: {{ toYaml .Values.controller.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.objectSelector }} + objectSelector: {{ toYaml .Values.controller.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/clusterrole.yaml b/nginx-ingress/templates/clusterrole.yaml new file mode 100644 index 0000000..c093f04 --- /dev/null +++ b/nginx-ingress/templates/clusterrole.yaml @@ -0,0 +1,87 @@ +{{- if .Values.rbac.create }} + +{{- if and .Values.rbac.scope (not .Values.controller.scope.enabled) -}} + {{ required "Invalid configuration: 'rbac.scope' should be equal to 'controller.scope.enabled' (true/false)." (index (dict) ".") }} +{{- end }} + +{{- if not .Values.rbac.scope -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} +rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets +{{- if not .Values.controller.scope.enabled }} + - namespaces +{{- end}} + verbs: + - list + - watch +{{- if and .Values.controller.scope.enabled .Values.controller.scope.namespace }} + - apiGroups: + - "" + resources: + - namespaces + resourceNames: + - "{{ .Values.controller.scope.namespace }}" + verbs: + - get +{{- end }} + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +{{- end }} + +{{- end }} diff --git a/nginx-ingress/templates/clusterrolebinding.yaml b/nginx-ingress/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..acbbd8b --- /dev/null +++ b/nginx-ingress/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.rbac.create (not .Values.rbac.scope) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ingress-nginx.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/nginx-ingress/templates/controller-configmap-addheaders.yaml b/nginx-ingress/templates/controller-configmap-addheaders.yaml new file mode 100644 index 0000000..dfd49a1 --- /dev/null +++ b/nginx-ingress/templates/controller-configmap-addheaders.yaml @@ -0,0 +1,14 @@ +{{- if .Values.controller.addHeaders -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-custom-add-headers + namespace: {{ .Release.Namespace }} +data: {{ toYaml .Values.controller.addHeaders | nindent 2 }} +{{- end }} diff --git a/nginx-ingress/templates/controller-configmap-proxyheaders.yaml b/nginx-ingress/templates/controller-configmap-proxyheaders.yaml new file mode 100644 index 0000000..f8d15fa --- /dev/null +++ b/nginx-ingress/templates/controller-configmap-proxyheaders.yaml @@ -0,0 +1,19 @@ +{{- if or .Values.controller.proxySetHeaders .Values.controller.headers -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-custom-proxy-headers + namespace: {{ .Release.Namespace }} +data: +{{- if .Values.controller.proxySetHeaders }} +{{ toYaml .Values.controller.proxySetHeaders | indent 2 }} +{{ else if and .Values.controller.headers (not .Values.controller.proxySetHeaders) }} +{{ toYaml .Values.controller.headers | indent 2 }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-configmap-tcp.yaml b/nginx-ingress/templates/controller-configmap-tcp.yaml new file mode 100644 index 0000000..0f6088e --- /dev/null +++ b/nginx-ingress/templates/controller-configmap-tcp.yaml @@ -0,0 +1,17 @@ +{{- if .Values.tcp -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.tcp.annotations }} + annotations: {{ toYaml .Values.controller.tcp.annotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.fullname" . }}-tcp + namespace: {{ .Release.Namespace }} +data: {{ tpl (toYaml .Values.tcp) . | nindent 2 }} +{{- end }} diff --git a/nginx-ingress/templates/controller-configmap-udp.yaml b/nginx-ingress/templates/controller-configmap-udp.yaml new file mode 100644 index 0000000..3772ec5 --- /dev/null +++ b/nginx-ingress/templates/controller-configmap-udp.yaml @@ -0,0 +1,17 @@ +{{- if .Values.udp -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.udp.annotations }} + annotations: {{ toYaml .Values.controller.udp.annotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.fullname" . }}-udp + namespace: {{ .Release.Namespace }} +data: {{ tpl (toYaml .Values.udp) . | nindent 2 }} +{{- end }} diff --git a/nginx-ingress/templates/controller-configmap.yaml b/nginx-ingress/templates/controller-configmap.yaml new file mode 100644 index 0000000..f28b26e --- /dev/null +++ b/nginx-ingress/templates/controller-configmap.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.configAnnotations }} + annotations: {{ toYaml .Values.controller.configAnnotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +data: + allow-snippet-annotations: "{{ .Values.controller.allowSnippetAnnotations }}" +{{- if .Values.controller.addHeaders }} + add-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-add-headers +{{- end }} +{{- if or .Values.controller.proxySetHeaders .Values.controller.headers }} + proxy-set-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-proxy-headers +{{- end }} +{{- if .Values.dhParam }} + ssl-dh-param: {{ printf "%s/%s" .Release.Namespace (include "ingress-nginx.controller.fullname" .) }} +{{- end }} +{{- range $key, $value := .Values.controller.config }} + {{- $key | nindent 2 }}: {{ $value | quote }} +{{- end }} + diff --git a/nginx-ingress/templates/controller-daemonset.yaml b/nginx-ingress/templates/controller-daemonset.yaml new file mode 100644 index 0000000..2dca8e5 --- /dev/null +++ b/nginx-ingress/templates/controller-daemonset.yaml @@ -0,0 +1,223 @@ +{{- if or (eq .Values.controller.kind "DaemonSet") (eq .Values.controller.kind "Both") -}} +{{- include "isControllerTagValid" . -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.controller.updateStrategy }} + updateStrategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }} + {{- end }} + minReadySeconds: {{ .Values.controller.minReadySeconds }} + template: + metadata: + {{- if .Values.controller.podAnnotations }} + annotations: + {{- range $key, $value := .Values.controller.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.controller.podLabels }} + {{- toYaml .Values.controller.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.dnsConfig }} + dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.controller.hostname }} + hostname: {{ toYaml .Values.controller.hostname | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName }} + {{- end }} + {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }} + securityContext: + {{- end }} + {{- if .Values.controller.podSecurityContext }} + {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} + {{- end }} + {{- if .Values.controller.sysctls }} + sysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - name: {{ $sysctl | quote }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.controller.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }} + {{- end }} + containers: + - name: {{ .Values.controller.containerName }} + {{- with .Values.controller.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}" + {{- end }} + imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + {{- if .Values.controller.lifecycle }} + lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }} + {{- end }} + args: + {{- include "ingress-nginx.params" . | nindent 12 }} + securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.enableMimalloc }} + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + {{- end }} + {{- if .Values.controller.extraEnvs }} + {{- toYaml .Values.controller.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.startupProbe }} + startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }} + {{- end }} + livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }} + readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }} + ports: + {{- range $key, $value := .Values.controller.containerPort }} + - name: {{ $key }} + containerPort: {{ $value }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }} + {{- end }} + {{- end }} + {{- if .Values.controller.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.controller.metrics.port }} + protocol: TCP + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook + containerPort: {{ .Values.controller.admissionWebhooks.port }} + protocol: TCP + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + containerPort: {{ $key }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + containerPort: {{ $key }} + protocol: UDP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules) }} + volumeMounts: + {{- if .Values.controller.extraModules }} + - name: modules + mountPath: /modules_mount + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - mountPath: /etc/nginx/template + name: nginx-template-volume + readOnly: true + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + mountPath: /usr/local/certificates/ + readOnly: true + {{- end }} + {{- if .Values.controller.extraVolumeMounts }} + {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.controller.resources }} + resources: {{ toYaml .Values.controller.resources | nindent 12 }} + {{- end }} + {{- if .Values.controller.extraContainers }} + {{ toYaml .Values.controller.extraContainers | nindent 8 }} + {{- end }} + + + {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules) }} + initContainers: + {{- if .Values.controller.extraInitContainers }} + {{ toYaml .Values.controller.extraInitContainers | nindent 8 }} + {{- end }} + {{- if .Values.controller.extraModules }} + {{- range .Values.controller.extraModules }} + - name: {{ .Name }} + image: {{ .Image }} + command: ['sh', '-c', '/usr/local/bin/init_module.sh'] + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules) }} + volumes: + {{- if .Values.controller.extraModules }} + - name: modules + emptyDir: {} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - name: nginx-template-volume + configMap: + name: {{ .Values.controller.customTemplate.configMapName }} + items: + - key: {{ .Values.controller.customTemplate.configMapKey }} + path: nginx.tmpl + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + secret: + secretName: {{ include "ingress-nginx.fullname" . }}-admission + {{- end }} + {{- if .Values.controller.extraVolumes }} + {{ toYaml .Values.controller.extraVolumes | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-deployment.yaml b/nginx-ingress/templates/controller-deployment.yaml new file mode 100644 index 0000000..5b781f8 --- /dev/null +++ b/nginx-ingress/templates/controller-deployment.yaml @@ -0,0 +1,228 @@ +{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}} +{{- include "isControllerTagValid" . -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicaCount }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.controller.updateStrategy }} + strategy: + {{ toYaml .Values.controller.updateStrategy | nindent 4 }} + {{- end }} + minReadySeconds: {{ .Values.controller.minReadySeconds }} + template: + metadata: + {{- if .Values.controller.podAnnotations }} + annotations: + {{- range $key, $value := .Values.controller.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.controller.podLabels }} + {{- toYaml .Values.controller.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.dnsConfig }} + dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.controller.hostname }} + hostname: {{ toYaml .Values.controller.hostname | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName | quote }} + {{- end }} + {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }} + securityContext: + {{- end }} + {{- if .Values.controller.podSecurityContext }} + {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} + {{- end }} + {{- if .Values.controller.sysctls }} + sysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - name: {{ $sysctl | quote }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.controller.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }} + {{- end }} + containers: + - name: {{ .Values.controller.containerName }} + {{- with .Values.controller.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}" + {{- end }} + imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + {{- if .Values.controller.lifecycle }} + lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }} + {{- end }} + args: + {{- include "ingress-nginx.params" . | nindent 12 }} + securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.enableMimalloc }} + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + {{- end }} + {{- if .Values.controller.extraEnvs }} + {{- toYaml .Values.controller.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.startupProbe }} + startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }} + {{- end }} + livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }} + readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }} + ports: + {{- range $key, $value := .Values.controller.containerPort }} + - name: {{ $key }} + containerPort: {{ $value }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }} + {{- end }} + {{- end }} + {{- if .Values.controller.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.controller.metrics.port }} + protocol: TCP + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook + containerPort: {{ .Values.controller.admissionWebhooks.port }} + protocol: TCP + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + containerPort: {{ $key }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + containerPort: {{ $key }} + protocol: UDP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules) }} + volumeMounts: + {{- if .Values.controller.extraModules }} + - name: modules + mountPath: /modules_mount + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - mountPath: /etc/nginx/template + name: nginx-template-volume + readOnly: true + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + mountPath: /usr/local/certificates/ + readOnly: true + {{- end }} + {{- if .Values.controller.extraVolumeMounts }} + {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.controller.resources }} + resources: {{ toYaml .Values.controller.resources | nindent 12 }} + {{- end }} + {{- if .Values.controller.extraContainers }} + {{ toYaml .Values.controller.extraContainers | nindent 8 }} + {{- end }} + {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules) }} + initContainers: + {{- if .Values.controller.extraInitContainers }} + {{ toYaml .Values.controller.extraInitContainers | nindent 8 }} + {{- end }} + {{- if .Values.controller.extraModules }} + {{- range .Values.controller.extraModules }} + - name: {{ .name }} + image: {{ .image }} + command: ['sh', '-c', '/usr/local/bin/init_module.sh'] + volumeMounts: + - name: modules + mountPath: /modules_mount + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules) }} + volumes: + {{- if .Values.controller.extraModules }} + - name: modules + emptyDir: {} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - name: nginx-template-volume + configMap: + name: {{ .Values.controller.customTemplate.configMapName }} + items: + - key: {{ .Values.controller.customTemplate.configMapKey }} + path: nginx.tmpl + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + secret: + secretName: {{ include "ingress-nginx.fullname" . }}-admission + {{- end }} + {{- if .Values.controller.extraVolumes }} + {{ toYaml .Values.controller.extraVolumes | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-hpa.yaml b/nginx-ingress/templates/controller-hpa.yaml new file mode 100644 index 0000000..e0979f1 --- /dev/null +++ b/nginx-ingress/templates/controller-hpa.yaml @@ -0,0 +1,52 @@ +{{- if and .Values.controller.autoscaling.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}} +{{- if not .Values.controller.keda.enabled }} + +apiVersion: autoscaling/v2beta2 +kind: HorizontalPodAutoscaler +metadata: + annotations: + {{- with .Values.controller.autoscaling.annotations }} + {{- toYaml . | trimSuffix "\n" | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ingress-nginx.controller.fullname" . }} + minReplicas: {{ .Values.controller.autoscaling.minReplicas }} + maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }} + metrics: + {{- with .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.controller.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.controller.autoscalingTemplate }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.controller.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} + diff --git a/nginx-ingress/templates/controller-ingressclass.yaml b/nginx-ingress/templates/controller-ingressclass.yaml new file mode 100644 index 0000000..9492784 --- /dev/null +++ b/nginx-ingress/templates/controller-ingressclass.yaml @@ -0,0 +1,21 @@ +{{- if .Values.controller.ingressClassResource.enabled -}} +# We don't support namespaced ingressClass yet +# So a ClusterRole and a ClusterRoleBinding is required +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ .Values.controller.ingressClassResource.name }} +{{- if .Values.controller.ingressClassResource.default }} + annotations: + ingressclass.kubernetes.io/is-default-class: "true" +{{- end }} +spec: + controller: {{ .Values.controller.ingressClassResource.controllerValue }} + {{ template "ingressClass.parameters" . }} +{{- end }} diff --git a/nginx-ingress/templates/controller-keda.yaml b/nginx-ingress/templates/controller-keda.yaml new file mode 100644 index 0000000..875157e --- /dev/null +++ b/nginx-ingress/templates/controller-keda.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.controller.keda.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}} +# https://keda.sh/docs/ + +apiVersion: {{ .Values.controller.keda.apiVersion }} +kind: ScaledObject +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + {{- if .Values.controller.keda.scaledObject.annotations }} + annotations: {{ toYaml .Values.controller.keda.scaledObject.annotations | nindent 4 }} + {{- end }} +spec: + scaleTargetRef: +{{- if eq .Values.controller.keda.apiVersion "keda.k8s.io/v1alpha1" }} + deploymentName: {{ include "ingress-nginx.controller.fullname" . }} +{{- else if eq .Values.controller.keda.apiVersion "keda.sh/v1alpha1" }} + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- end }} + pollingInterval: {{ .Values.controller.keda.pollingInterval }} + cooldownPeriod: {{ .Values.controller.keda.cooldownPeriod }} + minReplicaCount: {{ .Values.controller.keda.minReplicas }} + maxReplicaCount: {{ .Values.controller.keda.maxReplicas }} + triggers: +{{- with .Values.controller.keda.triggers }} +{{ toYaml . | indent 2 }} +{{ end }} + advanced: + restoreToOriginalReplicaCount: {{ .Values.controller.keda.restoreToOriginalReplicaCount }} +{{- if .Values.controller.keda.behavior }} + horizontalPodAutoscalerConfig: + behavior: +{{ with .Values.controller.keda.behavior -}} +{{ toYaml . | indent 8 }} +{{ end }} + +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-poddisruptionbudget.yaml b/nginx-ingress/templates/controller-poddisruptionbudget.yaml new file mode 100644 index 0000000..8dfbe98 --- /dev/null +++ b/nginx-ingress/templates/controller-poddisruptionbudget.yaml @@ -0,0 +1,19 @@ +{{- if or (and .Values.controller.autoscaling.enabled (gt (.Values.controller.autoscaling.minReplicas | int) 1)) (and (not .Values.controller.autoscaling.enabled) (gt (.Values.controller.replicaCount | int) 1)) }} +apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }} +kind: PodDisruptionBudget +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + minAvailable: {{ .Values.controller.minAvailable }} +{{- end }} diff --git a/nginx-ingress/templates/controller-prometheusrules.yaml b/nginx-ingress/templates/controller-prometheusrules.yaml new file mode 100644 index 0000000..ca54275 --- /dev/null +++ b/nginx-ingress/templates/controller-prometheusrules.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.prometheusRule.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.controller.metrics.prometheusRule.namespace }} + namespace: {{ .Values.controller.metrics.prometheusRule.namespace | quote }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.prometheusRule.additionalLabels }} + {{- toYaml .Values.controller.metrics.prometheusRule.additionalLabels | nindent 4 }} + {{- end }} +spec: +{{- if .Values.controller.metrics.prometheusRule.rules }} + groups: + - name: {{ template "ingress-nginx.name" . }} + rules: {{- toYaml .Values.controller.metrics.prometheusRule.rules | nindent 4 }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-psp.yaml b/nginx-ingress/templates/controller-psp.yaml new file mode 100644 index 0000000..fe34408 --- /dev/null +++ b/nginx-ingress/templates/controller-psp.yaml @@ -0,0 +1,92 @@ +{{- if and .Values.podSecurityPolicy.enabled (empty .Values.controller.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowedCapabilities: + - NET_BIND_SERVICE + {{- if .Values.controller.image.chroot }} + - SYS_CHROOT + {{- end }} +{{- if .Values.controller.sysctls }} + allowedUnsafeSysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - {{ $sysctl }} + {{- end }} +{{- end }} + privileged: false + allowPrivilegeEscalation: true + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + #- 'projected' + - 'secret' + #- 'downwardAPI' +{{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} +{{- end }} +{{- if or .Values.controller.hostNetwork .Values.controller.hostPort.enabled }} + hostPorts: +{{- if .Values.controller.hostNetwork }} +{{- range $key, $value := .Values.controller.containerPort }} + # {{ $key }} + - min: {{ $value }} + max: {{ $value }} +{{- end }} +{{- else if .Values.controller.hostPort.enabled }} +{{- range $key, $value := .Values.controller.hostPort.ports }} + # {{ $key }} + - min: {{ $value }} + max: {{ $value }} +{{- end }} +{{- end }} +{{- if .Values.controller.metrics.enabled }} + # metrics + - min: {{ .Values.controller.metrics.port }} + max: {{ .Values.controller.metrics.port }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.enabled }} + # admission webhooks + - min: {{ .Values.controller.admissionWebhooks.port }} + max: {{ .Values.controller.admissionWebhooks.port }} +{{- end }} +{{- range $key, $value := .Values.tcp }} + # {{ $key }}-tcp + - min: {{ $key }} + max: {{ $key }} +{{- end }} +{{- range $key, $value := .Values.udp }} + # {{ $key }}-udp + - min: {{ $key }} + max: {{ $key }} +{{- end }} +{{- end }} + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'MustRunAsNonRoot' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + seLinux: + rule: 'RunAsAny' +{{- end }} diff --git a/nginx-ingress/templates/controller-role.yaml b/nginx-ingress/templates/controller-role.yaml new file mode 100644 index 0000000..47bbc32 --- /dev/null +++ b/nginx-ingress/templates/controller-role.yaml @@ -0,0 +1,93 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - endpoints + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - configmaps + resourceNames: + - {{ .Values.controller.electionID }} + verbs: + - get + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: [{{ template "podSecurityPolicy.apiGroup" . }}] + resources: ['podsecuritypolicies'] + verbs: ['use'] + {{- with .Values.controller.existingPsp }} + resourceNames: [{{ . }}] + {{- else }} + resourceNames: [{{ include "ingress-nginx.fullname" . }}] + {{- end }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/controller-rolebinding.yaml b/nginx-ingress/templates/controller-rolebinding.yaml new file mode 100644 index 0000000..e846a11 --- /dev/null +++ b/nginx-ingress/templates/controller-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/nginx-ingress/templates/controller-service-internal.yaml b/nginx-ingress/templates/controller-service-internal.yaml new file mode 100644 index 0000000..aae3e15 --- /dev/null +++ b/nginx-ingress/templates/controller-service-internal.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.controller.service.enabled .Values.controller.service.internal.enabled .Values.controller.service.internal.annotations}} +apiVersion: v1 +kind: Service +metadata: + annotations: + {{- range $key, $value := .Values.controller.service.internal.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.service.labels }} + {{- toYaml .Values.controller.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-internal + namespace: {{ .Release.Namespace }} +spec: + type: "{{ .Values.controller.service.type }}" +{{- if .Values.controller.service.internal.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.service.internal.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.service.internal.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.service.internal.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.internal.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.service.internal.externalTrafficPolicy }} +{{- end }} + ports: + {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }} + {{- if .Values.controller.service.enableHttp }} + - name: http + port: {{ .Values.controller.service.ports.http }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.http }} + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: http + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }} + nodePort: {{ .Values.controller.service.nodePorts.http }} + {{- end }} + {{- end }} + {{- if .Values.controller.service.enableHttps }} + - name: https + port: {{ .Values.controller.service.ports.https }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.https }} + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: https + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }} + nodePort: {{ .Values.controller.service.nodePorts.https }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + port: {{ $key }} + protocol: TCP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + {{- if $.Values.controller.service.nodePorts.tcp }} + {{- if index $.Values.controller.service.nodePorts.tcp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + port: {{ $key }} + protocol: UDP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + {{- if $.Values.controller.service.nodePorts.udp }} + {{- if index $.Values.controller.service.nodePorts.udp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }} + {{- end }} + {{- end }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/nginx-ingress/templates/controller-service-metrics.yaml b/nginx-ingress/templates/controller-service-metrics.yaml new file mode 100644 index 0000000..0aaf414 --- /dev/null +++ b/nginx-ingress/templates/controller-service-metrics.yaml @@ -0,0 +1,45 @@ +{{- if .Values.controller.metrics.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.controller.metrics.service.annotations }} + annotations: {{ toYaml .Values.controller.metrics.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.service.labels }} + {{- toYaml .Values.controller.metrics.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-metrics + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.metrics.service.type }} +{{- if .Values.controller.metrics.service.clusterIP }} + clusterIP: {{ .Values.controller.metrics.service.clusterIP }} +{{- end }} +{{- if .Values.controller.metrics.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.metrics.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.metrics.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.metrics.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.metrics.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.metrics.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.metrics.service.externalTrafficPolicy }} +{{- end }} + ports: + - name: metrics + port: {{ .Values.controller.metrics.service.servicePort }} + protocol: TCP + targetPort: metrics + {{- $setNodePorts := (or (eq .Values.controller.metrics.service.type "NodePort") (eq .Values.controller.metrics.service.type "LoadBalancer")) }} + {{- if (and $setNodePorts (not (empty .Values.controller.metrics.service.nodePort))) }} + nodePort: {{ .Values.controller.metrics.service.nodePort }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/nginx-ingress/templates/controller-service-webhook.yaml b/nginx-ingress/templates/controller-service-webhook.yaml new file mode 100644 index 0000000..2aae24f --- /dev/null +++ b/nginx-ingress/templates/controller-service-webhook.yaml @@ -0,0 +1,40 @@ +{{- if .Values.controller.admissionWebhooks.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.controller.admissionWebhooks.service.annotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-admission + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.admissionWebhooks.service.type }} +{{- if .Values.controller.admissionWebhooks.service.clusterIP }} + clusterIP: {{ .Values.controller.admissionWebhooks.service.clusterIP }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.admissionWebhooks.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.admissionWebhooks.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} + ports: + - name: https-webhook + port: 443 + targetPort: webhook + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: https + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/nginx-ingress/templates/controller-service.yaml b/nginx-ingress/templates/controller-service.yaml new file mode 100644 index 0000000..2b28196 --- /dev/null +++ b/nginx-ingress/templates/controller-service.yaml @@ -0,0 +1,101 @@ +{{- if and .Values.controller.service.enabled .Values.controller.service.external.enabled -}} +apiVersion: v1 +kind: Service +metadata: + annotations: + {{- range $key, $value := .Values.controller.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.service.labels }} + {{- toYaml .Values.controller.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.service.type }} +{{- if .Values.controller.service.clusterIP }} + clusterIP: {{ .Values.controller.service.clusterIP }} +{{- end }} +{{- if .Values.controller.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.service.externalTrafficPolicy }} +{{- end }} +{{- if .Values.controller.service.sessionAffinity }} + sessionAffinity: {{ .Values.controller.service.sessionAffinity }} +{{- end }} +{{- if .Values.controller.service.healthCheckNodePort }} + healthCheckNodePort: {{ .Values.controller.service.healthCheckNodePort }} +{{- end }} +{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}} +{{- if .Values.controller.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.controller.service.ipFamilyPolicy }} +{{- end }} +{{- end }} +{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}} +{{- if .Values.controller.service.ipFamilies }} + ipFamilies: {{ toYaml .Values.controller.service.ipFamilies | nindent 4 }} +{{- end }} +{{- end }} + ports: + {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }} + {{- if .Values.controller.service.enableHttp }} + - name: http + port: {{ .Values.controller.service.ports.http }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.http }} + {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }} + appProtocol: http + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }} + nodePort: {{ .Values.controller.service.nodePorts.http }} + {{- end }} + {{- end }} + {{- if .Values.controller.service.enableHttps }} + - name: https + port: {{ .Values.controller.service.ports.https }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.https }} + {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }} + appProtocol: https + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }} + nodePort: {{ .Values.controller.service.nodePorts.https }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + port: {{ $key }} + protocol: TCP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + {{- if $.Values.controller.service.nodePorts.tcp }} + {{- if index $.Values.controller.service.nodePorts.tcp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + port: {{ $key }} + protocol: UDP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + {{- if $.Values.controller.service.nodePorts.udp }} + {{- if index $.Values.controller.service.nodePorts.udp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }} + {{- end }} + {{- end }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/nginx-ingress/templates/controller-serviceaccount.yaml b/nginx-ingress/templates/controller-serviceaccount.yaml new file mode 100644 index 0000000..824b2a1 --- /dev/null +++ b/nginx-ingress/templates/controller-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if or .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.serviceAccount.annotations }} + annotations: + {{ toYaml .Values.serviceAccount.annotations | indent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/nginx-ingress/templates/controller-servicemonitor.yaml b/nginx-ingress/templates/controller-servicemonitor.yaml new file mode 100644 index 0000000..4dbc6da --- /dev/null +++ b/nginx-ingress/templates/controller-servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.controller.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.controller.metrics.serviceMonitor.namespace | quote }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.controller.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: metrics + interval: {{ .Values.controller.metrics.serviceMonitor.scrapeInterval }} + {{- if .Values.controller.metrics.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.relabelings }} + relabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.metricRelabelings | nindent 8 }} + {{- end }} +{{- if .Values.controller.metrics.serviceMonitor.jobLabel }} + jobLabel: {{ .Values.controller.metrics.serviceMonitor.jobLabel | quote }} +{{- end }} +{{- if .Values.controller.metrics.serviceMonitor.namespaceSelector }} + namespaceSelector: {{ toYaml .Values.controller.metrics.serviceMonitor.namespaceSelector | nindent 4 }} +{{- else }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} +{{- if .Values.controller.metrics.serviceMonitor.targetLabels }} + targetLabels: + {{- range .Values.controller.metrics.serviceMonitor.targetLabels }} + - {{ . }} + {{- end }} +{{- end }} + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/nginx-ingress/templates/default-backend-deployment.yaml b/nginx-ingress/templates/default-backend-deployment.yaml new file mode 100644 index 0000000..fd3e96e --- /dev/null +++ b/nginx-ingress/templates/default-backend-deployment.yaml @@ -0,0 +1,118 @@ +{{- if .Values.defaultBackend.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: default-backend +{{- if not .Values.defaultBackend.autoscaling.enabled }} + replicas: {{ .Values.defaultBackend.replicaCount }} +{{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + template: + metadata: + {{- if .Values.defaultBackend.podAnnotations }} + annotations: {{ toYaml .Values.defaultBackend.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.podLabels }} + {{- toYaml .Values.defaultBackend.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.priorityClassName }} + priorityClassName: {{ .Values.defaultBackend.priorityClassName }} + {{- end }} + {{- if .Values.defaultBackend.podSecurityContext }} + securityContext: {{ toYaml .Values.defaultBackend.podSecurityContext | nindent 8 }} + {{- end }} + containers: + - name: {{ template "ingress-nginx.name" . }}-default-backend + {{- with .Values.defaultBackend.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.defaultBackend.image.pullPolicy }} + {{- if .Values.defaultBackend.extraArgs }} + args: + {{- range $key, $value := .Values.defaultBackend.extraArgs }} + {{- /* Accept keys without values or with false as value */}} + {{- if eq ($value | quote | len) 2 }} + - --{{ $key }} + {{- else }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- end }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + runAsUser: {{ .Values.defaultBackend.image.runAsUser }} + runAsNonRoot: {{ .Values.defaultBackend.image.runAsNonRoot }} + allowPrivilegeEscalation: {{ .Values.defaultBackend.image.allowPrivilegeEscalation }} + readOnlyRootFilesystem: {{ .Values.defaultBackend.image.readOnlyRootFilesystem}} + {{- if .Values.defaultBackend.extraEnvs }} + env: {{ toYaml .Values.defaultBackend.extraEnvs | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.defaultBackend.port }} + scheme: HTTP + initialDelaySeconds: {{ .Values.defaultBackend.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.defaultBackend.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.defaultBackend.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.defaultBackend.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.defaultBackend.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: {{ .Values.defaultBackend.port }} + scheme: HTTP + initialDelaySeconds: {{ .Values.defaultBackend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.defaultBackend.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.defaultBackend.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.defaultBackend.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.defaultBackend.readinessProbe.failureThreshold }} + ports: + - name: http + containerPort: {{ .Values.defaultBackend.port }} + protocol: TCP + {{- if .Values.defaultBackend.extraVolumeMounts }} + volumeMounts: {{- toYaml .Values.defaultBackend.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.defaultBackend.resources }} + resources: {{ toYaml .Values.defaultBackend.resources | nindent 12 }} + {{- end }} + {{- if .Values.defaultBackend.nodeSelector }} + nodeSelector: {{ toYaml .Values.defaultBackend.nodeSelector | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + {{- if .Values.defaultBackend.tolerations }} + tolerations: {{ toYaml .Values.defaultBackend.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.affinity }} + affinity: {{ toYaml .Values.defaultBackend.affinity | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 60 + {{- if .Values.defaultBackend.extraVolumes }} + volumes: {{ toYaml .Values.defaultBackend.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/default-backend-hpa.yaml b/nginx-ingress/templates/default-backend-hpa.yaml new file mode 100644 index 0000000..594d265 --- /dev/null +++ b/nginx-ingress/templates/default-backend-hpa.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "ingress-nginx.defaultBackend.fullname" . }} + minReplicas: {{ .Values.defaultBackend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.defaultBackend.autoscaling.maxReplicas }} + metrics: +{{- with .Values.defaultBackend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ . }} +{{- end }} +{{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ . }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/default-backend-poddisruptionbudget.yaml b/nginx-ingress/templates/default-backend-poddisruptionbudget.yaml new file mode 100644 index 0000000..00891ce --- /dev/null +++ b/nginx-ingress/templates/default-backend-poddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Values.defaultBackend.enabled -}} +{{- if or (gt (.Values.defaultBackend.replicaCount | int) 1) (gt (.Values.defaultBackend.autoscaling.minReplicas | int) 1) }} +apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }} +kind: PodDisruptionBudget +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: default-backend + minAvailable: {{ .Values.defaultBackend.minAvailable }} +{{- end }} +{{- end }} diff --git a/nginx-ingress/templates/default-backend-psp.yaml b/nginx-ingress/templates/default-backend-psp.yaml new file mode 100644 index 0000000..42061c5 --- /dev/null +++ b/nginx-ingress/templates/default-backend-psp.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled (empty .Values.defaultBackend.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-backend + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: false + fsGroup: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + requiredDropCapabilities: + - ALL + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI +{{- end }} diff --git a/nginx-ingress/templates/default-backend-role.yaml b/nginx-ingress/templates/default-backend-role.yaml new file mode 100644 index 0000000..a2b457c --- /dev/null +++ b/nginx-ingress/templates/default-backend-role.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-backend + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: [{{ template "podSecurityPolicy.apiGroup" . }}] + resources: ['podsecuritypolicies'] + verbs: ['use'] + {{- with .Values.defaultBackend.existingPsp }} + resourceNames: [{{ . }}] + {{- else }} + resourceNames: [{{ include "ingress-nginx.fullname" . }}-backend] + {{- end }} +{{- end }} diff --git a/nginx-ingress/templates/default-backend-rolebinding.yaml b/nginx-ingress/templates/default-backend-rolebinding.yaml new file mode 100644 index 0000000..dbaa516 --- /dev/null +++ b/nginx-ingress/templates/default-backend-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-backend + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }}-backend +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/nginx-ingress/templates/default-backend-service.yaml b/nginx-ingress/templates/default-backend-service.yaml new file mode 100644 index 0000000..5f1d09a --- /dev/null +++ b/nginx-ingress/templates/default-backend-service.yaml @@ -0,0 +1,41 @@ +{{- if .Values.defaultBackend.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.defaultBackend.service.annotations }} + annotations: {{ toYaml .Values.defaultBackend.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.defaultBackend.service.type }} +{{- if .Values.defaultBackend.service.clusterIP }} + clusterIP: {{ .Values.defaultBackend.service.clusterIP }} +{{- end }} +{{- if .Values.defaultBackend.service.externalIPs }} + externalIPs: {{ toYaml .Values.defaultBackend.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.defaultBackend.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.defaultBackend.service.loadBalancerIP }} +{{- end }} +{{- if .Values.defaultBackend.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.defaultBackend.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} + ports: + - name: http + port: {{ .Values.defaultBackend.service.servicePort }} + protocol: TCP + targetPort: http + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: http + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: default-backend +{{- end }} diff --git a/nginx-ingress/templates/default-backend-serviceaccount.yaml b/nginx-ingress/templates/default-backend-serviceaccount.yaml new file mode 100644 index 0000000..b45a95a --- /dev/null +++ b/nginx-ingress/templates/default-backend-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +automountServiceAccountToken: {{ .Values.defaultBackend.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/nginx-ingress/templates/dh-param-secret.yaml b/nginx-ingress/templates/dh-param-secret.yaml new file mode 100644 index 0000000..12e7a4f --- /dev/null +++ b/nginx-ingress/templates/dh-param-secret.yaml @@ -0,0 +1,10 @@ +{{- with .Values.dhParam -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "ingress-nginx.controller.fullname" $ }} + labels: + {{- include "ingress-nginx.labels" $ | nindent 4 }} +data: + dhparam.pem: {{ . }} +{{- end }} diff --git a/nginx-ingress/values.yaml b/nginx-ingress/values.yaml new file mode 100644 index 0000000..695f23b --- /dev/null +++ b/nginx-ingress/values.yaml @@ -0,0 +1,931 @@ +## nginx configuration +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/index.md +## + +## Overrides for generated resource names +# See templates/_helpers.tpl +# nameOverride: +# fullnameOverride: + +## Labels to apply to all resources +## +commonLabels: {} +# scmhash: abc123 +# myLabel: aakkmd + +controller: + name: controller + image: + ## Keep false as default for now! + chroot: false + registry: registry.k8s.io + image: ingress-nginx/controller + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: "v1.2.1" + digest: sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8 + digestChroot: sha256:d301551cf62bc3fb75c69fa56f7aa1d9e87b5079333adaf38afe84d9b7439355 + pullPolicy: IfNotPresent + # www-data -> uid 101 + runAsUser: 101 + allowPrivilegeEscalation: true + + # -- Use an existing PSP instead of creating one + existingPsp: "" + + # -- Configures the controller container name + containerName: controller + + # -- Configures the ports that the nginx-controller listens on + containerPort: + http: 80 + https: 443 + + # -- Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ + config: {} + + # -- Annotations to be added to the controller config configuration configmap. + configAnnotations: {} + + # -- Will add custom headers before sending traffic to backends according to https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/custom-headers + proxySetHeaders: {} + + # -- Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers + addHeaders: {} + + # -- Optionally customize the pod dnsConfig. + dnsConfig: {} + + # -- Optionally customize the pod hostname. + hostname: {} + + # -- Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. + # By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller + # to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. + dnsPolicy: ClusterFirst + + # -- Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network + # Ingress status was blank because there is no Service exposing the NGINX Ingress controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply + reportNodeInternalIp: false + + # -- Process Ingress objects without ingressClass annotation/ingressClassName field + # Overrides value for --watch-ingress-without-class flag of the controller binary + # Defaults to false + watchIngressWithoutClass: false + + # -- Process IngressClass per name (additionally as per spec.controller). + ingressClassByName: false + + # -- This configuration defines if Ingress Controller should allow users to set + # their own *-snippet annotations, otherwise this is forbidden / dropped + # when users add those annotations. + # Global snippets in ConfigMap are still respected + allowSnippetAnnotations: true + + # -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), + # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 + # is merged + hostNetwork: false + + ## Use host ports 80 and 443 + ## Disabled by default + hostPort: + # -- Enable 'hostPort' or not + enabled: false + ports: + # -- 'hostPort' http port + http: 80 + # -- 'hostPort' https port + https: 443 + + # -- Election ID to use for status update + electionID: ingress-controller-leader + + ## This section refers to the creation of the IngressClass resource + ## IngressClass resources are supported since k8s >= 1.18 and required since k8s >= 1.19 + ingressClassResource: + # -- Name of the ingressClass + name: nginx + # -- Is this ingressClass enabled or not + enabled: true + # -- Is this the default ingressClass for the cluster + default: false + # -- Controller-value of the controller that is processing this ingressClass + controllerValue: "k8s.io/ingress-nginx" + + # -- Parameters is a link to a custom resource containing additional + # configuration for the controller. This is optional if the controller + # does not require extra parameters. + parameters: {} + + # -- For backwards compatibility with ingress.class annotation, use ingressClass. + # Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation + ingressClass: nginx + + # -- Labels to add to the pod container metadata + podLabels: {} + # key: value + + # -- Security Context policies for controller pods + podSecurityContext: {} + + # -- See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls + sysctls: {} + # sysctls: + # "net.core.somaxconn": "8192" + + # -- Allows customization of the source of the IP address or FQDN to report + # in the ingress status field. By default, it reads the information provided + # by the service. If disable, the status field reports the IP address of the + # node or nodes where an ingress controller pod is running. + publishService: + # -- Enable 'publishService' or not + enabled: true + # -- Allows overriding of the publish service to bind to + # Must be / + pathOverride: "" + + # Limit the scope of the controller to a specific namespace + scope: + # -- Enable 'scope' or not + enabled: false + # -- Namespace to limit the controller to; defaults to $(POD_NAMESPACE) + namespace: "" + # -- When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels + # only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. + namespaceSelector: "" + + # -- Allows customization of the configmap / nginx-configmap namespace; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + + tcp: + # -- Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + # -- Annotations to be added to the tcp config configmap + annotations: {} + + udp: + # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + # -- Annotations to be added to the udp config configmap + annotations: {} + + # -- Maxmind license key to download GeoLite2 Databases. + ## https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases + maxmindLicenseKey: "" + + # -- Additional command line arguments to pass to nginx-ingress-controller + # E.g. to specify the default SSL certificate you can use + extraArgs: {} + ## extraArgs: + ## default-ssl-certificate: "/" + + # -- Additional environment variables to set + extraEnvs: [] + # extraEnvs: + # - name: FOO + # valueFrom: + # secretKeyRef: + # key: FOO + # name: secret-resource + + # -- Use a `DaemonSet` or `Deployment` + kind: Deployment + + # -- Annotations to be added to the controller Deployment or DaemonSet + ## + annotations: {} + # keel.sh/pollSchedule: "@every 60m" + + # -- Labels to be added to the controller Deployment or DaemonSet and other resources that do not have option to specify labels + ## + labels: {} + # keel.sh/policy: patch + # keel.sh/trigger: poll + + + # -- The update strategy to apply to the Deployment or DaemonSet + ## + updateStrategy: {} + # rollingUpdate: + # maxUnavailable: 1 + # type: RollingUpdate + + # -- `minReadySeconds` to avoid killing pods before we are ready + ## + minReadySeconds: 0 + + + # -- Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + # -- Affinity and anti-affinity rules for server scheduling to nodes + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + # # An example of preferred pod anti-affinity, weight is in the range 1-100 + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 100 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: kubernetes.io/hostname + + # # An example of required pod anti-affinity + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: "kubernetes.io/hostname" + + # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app.kubernetes.io/instance: ingress-nginx-internal + + # -- `terminationGracePeriodSeconds` to avoid killing pods before we are ready + ## wait up to five minutes for the drain of connections + ## + terminationGracePeriodSeconds: 300 + + # -- Node labels for controller pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: + kubernetes.io/os: linux + + ## Liveness and readiness probe values + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## + ## startupProbe: + ## httpGet: + ## # should match container.healthCheckPath + ## path: "/healthz" + ## port: 10254 + ## scheme: HTTP + ## initialDelaySeconds: 5 + ## periodSeconds: 5 + ## timeoutSeconds: 2 + ## successThreshold: 1 + ## failureThreshold: 5 + livenessProbe: + httpGet: + # should match container.healthCheckPath + path: "/healthz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + httpGet: + # should match container.healthCheckPath + path: "/healthz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + + + # -- Path of the health check endpoint. All requests received on the port defined by + # the healthz-port parameter are forwarded internally to this path. + healthCheckPath: "/healthz" + + # -- Address to bind the health check endpoint. + # It is better to set this option to the internal node address + # if the ingress nginx controller is running in the `hostNetwork: true` mode. + healthCheckHost: "" + + # -- Annotations to be added to controller pods + ## + podAnnotations: {} + + replicaCount: 1 + + minAvailable: 1 + + ## Define requests resources to avoid probe issues due to CPU utilization in busy nodes + ## ref: https://github.com/kubernetes/ingress-nginx/issues/4735#issuecomment-551204903 + ## Ideally, there should be no limits. + ## https://engineering.indeedblog.com/blog/2019/12/cpu-throttling-regression-fix/ + resources: + ## limits: + ## cpu: 100m + ## memory: 90Mi + requests: + cpu: 100m + memory: 90Mi + + # Mutually exclusive with keda autoscaling + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 11 + targetCPUUtilizationPercentage: 50 + targetMemoryUtilizationPercentage: 50 + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + + autoscalingTemplate: [] + # Custom or additional autoscaling metrics + # ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-custom-metrics + # - type: Pods + # pods: + # metric: + # name: nginx_ingress_controller_nginx_process_requests_total + # target: + # type: AverageValue + # averageValue: 10000m + + # Mutually exclusive with hpa autoscaling + keda: + apiVersion: "keda.sh/v1alpha1" + ## apiVersion changes with keda 1.x vs 2.x + ## 2.x = keda.sh/v1alpha1 + ## 1.x = keda.k8s.io/v1alpha1 + enabled: false + minReplicas: 1 + maxReplicas: 11 + pollingInterval: 30 + cooldownPeriod: 300 + restoreToOriginalReplicaCount: false + scaledObject: + annotations: {} + # Custom annotations for ScaledObject resource + # annotations: + # key: value + triggers: [] + # - type: prometheus + # metadata: + # serverAddress: http://:9090 + # metricName: http_requests_total + # threshold: '100' + # query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) + + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + + # -- Enable mimalloc as a drop-in replacement for malloc. + ## ref: https://github.com/microsoft/mimalloc + ## + enableMimalloc: true + + ## Override NGINX template + customTemplate: + configMapName: "" + configMapKey: "" + + service: + enabled: true + + # -- If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were + # using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http + # It allows choosing the protocol for each backend specified in the Kubernetes service. + # See the following GitHub issue for more details about the purpose: https://github.com/kubernetes/kubernetes/issues/40244 + # Will be ignored for Kubernetes versions older than 1.20 + ## + appProtocol: true + + annotations: {} + labels: {} + # clusterIP: "" + + # -- List of IP addresses at which the controller services are available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + # -- Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + loadBalancerIP: "" + loadBalancerSourceRanges: [] + + enableHttp: true + enableHttps: true + + ## Set external traffic policy to: "Local" to preserve source IP on providers supporting it. + ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer + # externalTrafficPolicy: "" + + ## Must be either "None" or "ClientIP" if set. Kubernetes will default to "None". + ## Ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + # sessionAffinity: "" + + ## Specifies the health check node port (numeric port number) for the service. If healthCheckNodePort isn’t specified, + ## the service controller allocates a port from your cluster’s NodePort range. + ## Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + # healthCheckNodePort: 0 + + # -- Represents the dual-stack-ness requested or required by this Service. Possible values are + # SingleStack, PreferDualStack or RequireDualStack. + # The ipFamilies and clusterIPs fields depend on the value of this field. + ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ + ipFamilyPolicy: "SingleStack" + + # -- List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically + # based on cluster configuration and the ipFamilyPolicy field. + ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ + ipFamilies: + - IPv4 + + ports: + http: 80 + https: 443 + + targetPorts: + http: http + https: https + + type: LoadBalancer + + ## type: NodePort + ## nodePorts: + ## http: 32080 + ## https: 32443 + ## tcp: + ## 8080: 32808 + nodePorts: + http: "" + https: "" + tcp: {} + udp: {} + + external: + enabled: true + + internal: + # -- Enables an additional internal load balancer (besides the external one). + enabled: false + # -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service. + annotations: {} + + # loadBalancerIP: "" + + # -- Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. + loadBalancerSourceRanges: [] + + ## Set external traffic policy to: "Local" to preserve source IP on + ## providers supporting it + ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer + # externalTrafficPolicy: "" + + # shareProcessNamespace enables process namespace sharing within the pod. + # This can be used for example to signal log rotation using `kill -USR1` from a sidecar. + shareProcessNamespace: false + + # -- Additional containers to be added to the controller pod. + # See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. + extraContainers: [] + # - name: my-sidecar + # image: nginx:latest + # - name: lemonldap-ng-controller + # image: lemonldapng/lemonldap-ng-controller:0.2.0 + # args: + # - /lemonldap-ng-controller + # - --alsologtostderr + # - --configmap=$(POD_NAMESPACE)/lemonldap-ng-configuration + # env: + # - name: POD_NAME + # valueFrom: + # fieldRef: + # fieldPath: metadata.name + # - name: POD_NAMESPACE + # valueFrom: + # fieldRef: + # fieldPath: metadata.namespace + # volumeMounts: + # - name: copy-portal-skins + # mountPath: /srv/var/lib/lemonldap-ng/portal/skins + + # -- Additional volumeMounts to the controller main container. + extraVolumeMounts: [] + # - name: copy-portal-skins + # mountPath: /var/lib/lemonldap-ng/portal/skins + + # -- Additional volumes to the controller pod. + extraVolumes: [] + # - name: copy-portal-skins + # emptyDir: {} + + # -- Containers, which are run before the app containers are started. + extraInitContainers: [] + # - name: init-myservice + # image: busybox + # command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] + + extraModules: [] + ## Modules, which are mounted into the core nginx image + # - name: opentelemetry + # image: registry.k8s.io/ingress-nginx/opentelemetry:v20220415-controller-v1.2.0-beta.0-2-g81c2afd97@sha256:ce61e2cf0b347dffebb2dcbf57c33891d2217c1bad9c0959c878e5be671ef941 + # + # The image must contain a `/usr/local/bin/init_module.sh` executable, which + # will be executed as initContainers, to move its config files within the + # mounted volume. + + admissionWebhooks: + annotations: {} + # ignore-check.kube-linter.io/no-read-only-rootfs: "This deployment needs write access to root filesystem". + + ## Additional annotations to the admission webhooks. + ## These annotations will be added to the ValidatingWebhookConfiguration and + ## the Jobs Spec of the admission webhooks. + enabled: true + failurePolicy: Fail + # timeoutSeconds: 10 + port: 8443 + certificate: "/usr/local/certificates/cert" + key: "/usr/local/certificates/key" + namespaceSelector: {} + objectSelector: {} + # -- Labels to be added to admission webhooks + labels: {} + + # -- Use an existing PSP instead of creating one + existingPsp: "" + + service: + annotations: {} + # clusterIP: "" + externalIPs: [] + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 443 + type: ClusterIP + + createSecretJob: + resources: {} + # limits: + # cpu: 10m + # memory: 20Mi + # requests: + # cpu: 10m + # memory: 20Mi + + patchWebhookJob: + resources: {} + + patch: + enabled: true + image: + registry: registry.k8s.io + image: ingress-nginx/kube-webhook-certgen + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: v1.1.1 + digest: sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + pullPolicy: IfNotPresent + # -- Provide a priority class name to the webhook patching job + ## + priorityClassName: "" + podAnnotations: {} + nodeSelector: + kubernetes.io/os: linux + tolerations: [] + # -- Labels to be added to patch job resources + labels: {} + runAsUser: 2000 + fsGroup: 2000 + + metrics: + port: 10254 + # if this port is changed, change healthz-port: in extraArgs: accordingly + enabled: false + + service: + annotations: {} + # prometheus.io/scrape: "true" + # prometheus.io/port: "10254" + + # clusterIP: "" + + # -- List of IP addresses at which the stats-exporter service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 10254 + type: ClusterIP + # externalTrafficPolicy: "" + # nodePort: "" + + serviceMonitor: + enabled: false + additionalLabels: {} + ## The label to use to retrieve the job name from. + ## jobLabel: "app.kubernetes.io/name" + namespace: "" + namespaceSelector: {} + ## Default: scrape .Release.Namespace only + ## To scrape all, use the following: + ## namespaceSelector: + ## any: true + scrapeInterval: 30s + # honorLabels: true + targetLabels: [] + relabelings: [] + metricRelabelings: [] + + prometheusRule: + enabled: false + additionalLabels: {} + # namespace: "" + rules: [] + # # These are just examples rules, please adapt them to your needs + # - alert: NGINXConfigFailed + # expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: bad ingress config - nginx config test failed + # summary: uninstall the latest ingress changes to allow config reloads to resume + # - alert: NGINXCertificateExpiry + # expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: ssl certificate(s) will expire in less then a week + # summary: renew expiring certificates to avoid downtime + # - alert: NGINXTooMany500s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"5.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 5XXs + # summary: More than 5% of all requests returned 5XX, this requires your attention + # - alert: NGINXTooMany400s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"4.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 4XXs + # summary: More than 5% of all requests returned 4XX, this requires your attention + + # -- Improve connection draining when ingress controller pod is deleted using a lifecycle hook: + # With this new hook, we increased the default terminationGracePeriodSeconds from 30 seconds + # to 300, allowing the draining of connections up to five minutes. + # If the active connections end before that, the pod will terminate gracefully at that time. + # To effectively take advantage of this feature, the Configmap feature + # worker-shutdown-timeout new value is 240s instead of 10s. + ## + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + + priorityClassName: "" + +# -- Rollback limit +## +revisionHistoryLimit: 10 + +## Default 404 backend +## +defaultBackend: + ## + enabled: false + + name: defaultbackend + image: + registry: registry.k8s.io + image: defaultbackend-amd64 + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: "1.5" + pullPolicy: IfNotPresent + # nobody user -> uid 65534 + runAsUser: 65534 + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + + # -- Use an existing PSP instead of creating one + existingPsp: "" + + extraArgs: {} + + serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + # -- Additional environment variables to set for defaultBackend pods + extraEnvs: [] + + port: 8080 + + ## Readiness and liveness probes for default backend + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + ## + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 0 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + + # -- Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + affinity: {} + + # -- Security Context policies for controller pods + # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for + # notes on enabling and using sysctls + ## + podSecurityContext: {} + + # -- Security Context policies for controller main container. + # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for + # notes on enabling and using sysctls + ## + containerSecurityContext: {} + + # -- Labels to add to the pod container metadata + podLabels: {} + # key: value + + # -- Node labels for default backend pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: + kubernetes.io/os: linux + + # -- Annotations to be added to default backend pods + ## + podAnnotations: {} + + replicaCount: 1 + + minAvailable: 1 + + resources: {} + # limits: + # cpu: 10m + # memory: 20Mi + # requests: + # cpu: 10m + # memory: 20Mi + + extraVolumeMounts: [] + ## Additional volumeMounts to the default backend container. + # - name: copy-portal-skins + # mountPath: /var/lib/lemonldap-ng/portal/skins + + extraVolumes: [] + ## Additional volumes to the default backend pod. + # - name: copy-portal-skins + # emptyDir: {} + + autoscaling: + annotations: {} + enabled: false + minReplicas: 1 + maxReplicas: 2 + targetCPUUtilizationPercentage: 50 + targetMemoryUtilizationPercentage: 50 + + service: + annotations: {} + + # clusterIP: "" + + # -- List of IP addresses at which the default backend service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + type: ClusterIP + + priorityClassName: "" + # -- Labels to be added to the default backend resources + labels: {} + +## Enable RBAC as per https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/rbac.md and https://github.com/kubernetes/ingress-nginx/issues/266 +rbac: + create: true + scope: false + +## If true, create & use Pod Security Policy resources +## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +podSecurityPolicy: + enabled: false + +serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + # -- Annotations for the controller service account + annotations: {} + +# -- Optional array of imagePullSecrets containing private registry credentials +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: secretName + +# -- TCP service key-value pairs +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md +## +tcp: {} +# 8080: "default/example-tcp-svc:9000" + +# -- UDP service key-value pairs +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md +## +udp: {} +# 53: "kube-system/kube-dns:53" + +# -- Prefix for TCP and UDP ports names in ingress controller service +## Some cloud providers, like Yandex Cloud may have a requirements for a port name regex to support cloud load balancer integration +portNamePrefix: "" + +# -- (string) A base64-encoded Diffie-Hellman parameter. +# This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` +## Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param +dhParam: From 1bb467f10927f34872d47ae3c38a29528cafb9ba Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 15:46:31 +0400 Subject: [PATCH 04/17] rrreee --- metal-lb/values.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/metal-lb/values.yaml b/metal-lb/values.yaml index b0eaa06..0bfc2bc 100644 --- a/metal-lb/values.yaml +++ b/metal-lb/values.yaml @@ -66,7 +66,12 @@ existingConfigMap: "" ## Refer to https://metallb.universe.tf/configuration/ for ## available options. ## -configInline: {} +configInline: + address-pools: + name: generic-cluster-pool + protocol: layer2 + addresses: + - 172.18.0.240/29 ## RBAC creation for controller and speaker ## rbac: From bafecc4155ecca0b2a4ba57a6f588af254997896 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 15:55:15 +0400 Subject: [PATCH 05/17] asda --- metal-lb/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metal-lb/values.yaml b/metal-lb/values.yaml index 0bfc2bc..b1a6fa9 100644 --- a/metal-lb/values.yaml +++ b/metal-lb/values.yaml @@ -68,7 +68,7 @@ existingConfigMap: "" ## configInline: address-pools: - name: generic-cluster-pool + name: default protocol: layer2 addresses: - 172.18.0.240/29 From 9824497daaf98996f768edec7be8974d2b6d6ffa Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 15:57:57 +0400 Subject: [PATCH 06/17] asd --- metal-lb/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metal-lb/values.yaml b/metal-lb/values.yaml index b1a6fa9..42e6ea3 100644 --- a/metal-lb/values.yaml +++ b/metal-lb/values.yaml @@ -71,7 +71,7 @@ configInline: name: default protocol: layer2 addresses: - - 172.18.0.240/29 + - 172.18.0.241-172.18.0.246 ## RBAC creation for controller and speaker ## rbac: From 0c90cd0036d231549a81425ac96abc43daa4b817 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 17 Jun 2022 16:00:24 +0400 Subject: [PATCH 07/17] asdasd --- metal-lb/values.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/metal-lb/values.yaml b/metal-lb/values.yaml index 42e6ea3..045c826 100644 --- a/metal-lb/values.yaml +++ b/metal-lb/values.yaml @@ -68,10 +68,10 @@ existingConfigMap: "" ## configInline: address-pools: - name: default - protocol: layer2 - addresses: - - 172.18.0.241-172.18.0.246 + - name: default + protocol: layer2 + addresses: + - 172.18.0.241-172.18.0.246 ## RBAC creation for controller and speaker ## rbac: From 7d40b5a2f3ab57df8a92dcbce18f90216a975108 Mon Sep 17 00:00:00 2001 From: Marat Date: Sat, 18 Jun 2022 19:37:12 +0400 Subject: [PATCH 08/17] asdasd --- apps/templates/cert-manager.yaml | 16 + cert-manager/Chart.yaml | 22 + cert-manager/README.md | 220 + cert-manager/templates/NOTES.txt | 15 + cert-manager/templates/_helpers.tpl | 159 + .../templates/cainjector-deployment.yaml | 102 + .../templates/cainjector-psp-clusterrole.yaml | 20 + .../cainjector-psp-clusterrolebinding.yaml | 22 + cert-manager/templates/cainjector-psp.yaml | 51 + cert-manager/templates/cainjector-rbac.yaml | 103 + .../templates/cainjector-serviceaccount.yaml | 27 + cert-manager/templates/crds.yaml | 4280 +++++++++++++++++ cert-manager/templates/deployment.yaml | 170 + cert-manager/templates/psp-clusterrole.yaml | 18 + .../templates/psp-clusterrolebinding.yaml | 20 + cert-manager/templates/psp.yaml | 49 + cert-manager/templates/rbac.yaml | 545 +++ cert-manager/templates/service.yaml | 31 + cert-manager/templates/serviceaccount.yaml | 25 + cert-manager/templates/servicemonitor.yaml | 39 + .../templates/startupapicheck-job.yaml | 77 + .../startupapicheck-psp-clusterrole.yaml | 24 + ...tartupapicheck-psp-clusterrolebinding.yaml | 26 + .../templates/startupapicheck-psp.yaml | 51 + .../templates/startupapicheck-rbac.yaml | 48 + .../startupapicheck-serviceaccount.yaml | 27 + cert-manager/templates/webhook-config.yaml | 24 + .../templates/webhook-deployment.yaml | 153 + .../templates/webhook-mutating-webhook.yaml | 46 + .../templates/webhook-psp-clusterrole.yaml | 18 + .../webhook-psp-clusterrolebinding.yaml | 20 + cert-manager/templates/webhook-psp.yaml | 54 + cert-manager/templates/webhook-rbac.yaml | 83 + cert-manager/templates/webhook-service.yaml | 32 + .../templates/webhook-serviceaccount.yaml | 25 + .../templates/webhook-validating-webhook.yaml | 55 + cert-manager/values.yaml | 543 +++ 37 files changed, 7240 insertions(+) create mode 100644 apps/templates/cert-manager.yaml create mode 100644 cert-manager/Chart.yaml create mode 100644 cert-manager/README.md create mode 100644 cert-manager/templates/NOTES.txt create mode 100644 cert-manager/templates/_helpers.tpl create mode 100644 cert-manager/templates/cainjector-deployment.yaml create mode 100644 cert-manager/templates/cainjector-psp-clusterrole.yaml create mode 100644 cert-manager/templates/cainjector-psp-clusterrolebinding.yaml create mode 100644 cert-manager/templates/cainjector-psp.yaml create mode 100644 cert-manager/templates/cainjector-rbac.yaml create mode 100644 cert-manager/templates/cainjector-serviceaccount.yaml create mode 100644 cert-manager/templates/crds.yaml create mode 100644 cert-manager/templates/deployment.yaml create mode 100644 cert-manager/templates/psp-clusterrole.yaml create mode 100644 cert-manager/templates/psp-clusterrolebinding.yaml create mode 100644 cert-manager/templates/psp.yaml create mode 100644 cert-manager/templates/rbac.yaml create mode 100644 cert-manager/templates/service.yaml create mode 100644 cert-manager/templates/serviceaccount.yaml create mode 100644 cert-manager/templates/servicemonitor.yaml create mode 100644 cert-manager/templates/startupapicheck-job.yaml create mode 100644 cert-manager/templates/startupapicheck-psp-clusterrole.yaml create mode 100644 cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml create mode 100644 cert-manager/templates/startupapicheck-psp.yaml create mode 100644 cert-manager/templates/startupapicheck-rbac.yaml create mode 100644 cert-manager/templates/startupapicheck-serviceaccount.yaml create mode 100644 cert-manager/templates/webhook-config.yaml create mode 100644 cert-manager/templates/webhook-deployment.yaml create mode 100644 cert-manager/templates/webhook-mutating-webhook.yaml create mode 100644 cert-manager/templates/webhook-psp-clusterrole.yaml create mode 100644 cert-manager/templates/webhook-psp-clusterrolebinding.yaml create mode 100644 cert-manager/templates/webhook-psp.yaml create mode 100644 cert-manager/templates/webhook-rbac.yaml create mode 100644 cert-manager/templates/webhook-service.yaml create mode 100644 cert-manager/templates/webhook-serviceaccount.yaml create mode 100644 cert-manager/templates/webhook-validating-webhook.yaml create mode 100644 cert-manager/values.yaml diff --git a/apps/templates/cert-manager.yaml b/apps/templates/cert-manager.yaml new file mode 100644 index 0000000..7d59ffc --- /dev/null +++ b/apps/templates/cert-manager.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: cert-manager + namespace: cert-manager + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: cert-manager + server: {{ .Values.spec.destination.server }} + project: default + source: + path: cert-manager + repoURL: {{ .Values.spec.source.repoURL }} + targetRevision: {{ .Values.spec.source.targetRevision }} diff --git a/cert-manager/Chart.yaml b/cert-manager/Chart.yaml new file mode 100644 index 0000000..0484173 --- /dev/null +++ b/cert-manager/Chart.yaml @@ -0,0 +1,22 @@ +annotations: + artifacthub.io/prerelease: "false" + artifacthub.io/signKey: | + fingerprint: 1020CF3C033D4F35BAE1C19E1226061C665DF13E + url: https://cert-manager.io/public-keys/cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg +apiVersion: v1 +appVersion: v1.8.1 +description: A Helm chart for cert-manager +home: https://github.com/cert-manager/cert-manager +icon: https://raw.githubusercontent.com/cert-manager/cert-manager/master/logo/logo.png +keywords: +- cert-manager +- kube-lego +- letsencrypt +- tls +maintainers: +- email: cert-manager-maintainers@googlegroups.com + name: cert-manager-maintainers +name: cert-manager +sources: +- https://github.com/cert-manager/cert-manager +version: v1.8.1 diff --git a/cert-manager/README.md b/cert-manager/README.md new file mode 100644 index 0000000..addc9bb --- /dev/null +++ b/cert-manager/README.md @@ -0,0 +1,220 @@ +# cert-manager + +cert-manager is a Kubernetes addon to automate the management and issuance of +TLS certificates from various issuing sources. + +It will ensure certificates are valid and up to date periodically, and attempt +to renew certificates at an appropriate time before expiry. + +## Prerequisites + +- Kubernetes 1.18+ + +## Installing the Chart + +Full installation instructions, including details on how to configure extra +functionality in cert-manager can be found in the [installation docs](https://cert-manager.io/docs/installation/kubernetes/). + +Before installing the chart, you must first install the cert-manager CustomResourceDefinition resources. +This is performed in a separate step to allow you to easily uninstall and reinstall cert-manager without deleting your installed custom resources. + +```bash +$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.1/cert-manager.crds.yaml +``` + +To install the chart with the release name `my-release`: + +```console +## Add the Jetstack Helm repository +$ helm repo add jetstack https://charts.jetstack.io + +## Install the cert-manager helm chart +$ helm install my-release --namespace cert-manager --version v1.8.1 jetstack/cert-manager +``` + +In order to begin issuing certificates, you will need to set up a ClusterIssuer +or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). + +More information on the different types of issuers and how to configure them +can be found in [our documentation](https://cert-manager.io/docs/configuration/). + +For information on how to configure cert-manager to automatically provision +Certificates for Ingress resources, take a look at the +[Securing Ingresses documentation](https://cert-manager.io/docs/usage/ingress/). + +> **Tip**: List all releases using `helm list` + +## Upgrading the Chart + +Special considerations may be required when upgrading the Helm chart, and these +are documented in our full [upgrading guide](https://cert-manager.io/docs/installation/upgrading/). + +**Please check here before performing upgrades!** + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +If you want to completely uninstall cert-manager from your cluster, you will also need to +delete the previously installed CustomResourceDefinition resources: + +```console +$ kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.1/cert-manager.crds.yaml +``` + +## Configuration + +The following table lists the configurable parameters of the cert-manager chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `global.imagePullSecrets` | Reference to one or more secrets to be used when pulling images | `[]` | +| `global.rbac.create` | If `true`, create and use RBAC resources (includes sub-charts) | `true` | +| `global.priorityClassName`| Priority class name for cert-manager and webhook pods | `""` | +| `global.podSecurityPolicy.enabled` | If `true`, create and use PodSecurityPolicy (includes sub-charts) | `false` | +| `global.podSecurityPolicy.useAppArmor` | If `true`, use Apparmor seccomp profile in PSP | `true` | +| `global.leaderElection.namespace` | Override the namespace used to store the ConfigMap for leader election | `kube-system` | +| `global.leaderElection.leaseDuration` | The duration that non-leader candidates will wait after observing a leadership renewal until attempting to acquire leadership of a led but unrenewed leader slot. This is effectively the maximum duration that a leader can be stopped before it is replaced by another candidate | | +| `global.leaderElection.renewDeadline` | The interval between attempts by the acting master to renew a leadership slot before it stops leading. This must be less than or equal to the lease duration | | +| `global.leaderElection.retryPeriod` | The duration the clients should wait between attempting acquisition and renewal of a leadership | | +| `installCRDs` | If true, CRD resources will be installed as part of the Helm chart. If enabled, when uninstalling CRD resources will be deleted causing all installed custom resources to be DELETED | `false` | +| `image.repository` | Image repository | `quay.io/jetstack/cert-manager-controller` | +| `image.tag` | Image tag | `v1.8.1` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `replicaCount` | Number of cert-manager replicas | `1` | +| `clusterResourceNamespace` | Override the namespace used to store DNS provider credentials etc. for ClusterIssuer resources | Same namespace as cert-manager pod | +| `featureGates` | Set of comma-separated key=value pairs that describe feature gates on the controller. Some feature gates may also have to be enabled on other components, and can be set supplying the `feature-gate` flag to `.extraArgs` | `` | +| `extraArgs` | Optional flags for cert-manager | `[]` | +| `extraEnv` | Optional environment variables for cert-manager | `[]` | +| `serviceAccount.create` | If `true`, create a new service account | `true` | +| `serviceAccount.name` | Service account to be used. If not set and `serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `serviceAccount.annotations` | Annotations to add to the service account | | +| `serviceAccount.automountServiceAccountToken` | Automount API credentials for the Service Account | `true` | +| `volumes` | Optional volumes for cert-manager | `[]` | +| `volumeMounts` | Optional volume mounts for cert-manager | `[]` | +| `resources` | CPU/memory resource requests/limits | `{}` | +| `securityContext` | Optional security context. The yaml block should adhere to the [SecurityContext spec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#securitycontext-v1-core) | `{}` | +| `securityContext.enabled` | Deprecated (use `securityContext`) - Enable security context | `false` | +| `containerSecurityContext` | Security context to be set on the controller component container | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `affinity` | Node affinity for pod assignment | `{}` | +| `tolerations` | Node tolerations for pod assignment | `[]` | +| `ingressShim.defaultIssuerName` | Optional default issuer to use for ingress resources | | +| `ingressShim.defaultIssuerKind` | Optional default issuer kind to use for ingress resources | | +| `ingressShim.defaultIssuerGroup` | Optional default issuer group to use for ingress resources | | +| `prometheus.enabled` | Enable Prometheus monitoring | `true` | +| `prometheus.servicemonitor.enabled` | Enable Prometheus Operator ServiceMonitor monitoring | `false` | +| `prometheus.servicemonitor.namespace` | Define namespace where to deploy the ServiceMonitor resource | (namespace where you are deploying) | +| `prometheus.servicemonitor.prometheusInstance` | Prometheus Instance definition | `default` | +| `prometheus.servicemonitor.targetPort` | Prometheus scrape port | `9402` | +| `prometheus.servicemonitor.path` | Prometheus scrape path | `/metrics` | +| `prometheus.servicemonitor.interval` | Prometheus scrape interval | `60s` | +| `prometheus.servicemonitor.labels` | Add custom labels to ServiceMonitor | | +| `prometheus.servicemonitor.scrapeTimeout` | Prometheus scrape timeout | `30s` | +| `prometheus.servicemonitor.honorLabels` | Enable label honoring for metrics scraped by Prometheus (see [Prometheus scrape config docs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) for details). By setting `honorLabels` to `true`, Prometheus will prefer label contents given by cert-manager on conflicts. Can be used to remove the "exported_namespace" label for example. | `false` | +| `podAnnotations` | Annotations to add to the cert-manager pod | `{}` | +| `deploymentAnnotations` | Annotations to add to the cert-manager deployment | `{}` | +| `podDnsPolicy` | Optional cert-manager pod [DNS policy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-policy) | | +| `podDnsConfig` | Optional cert-manager pod [DNS configurations](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-config) | | +| `podLabels` | Labels to add to the cert-manager pod | `{}` | +| `serviceLabels` | Labels to add to the cert-manager controller service | `{}` | +| `serviceAnnotations` | Annotations to add to the cert-manager service | `{}` | +| `http_proxy` | Value of the `HTTP_PROXY` environment variable in the cert-manager pod | | +| `https_proxy` | Value of the `HTTPS_PROXY` environment variable in the cert-manager pod | | +| `no_proxy` | Value of the `NO_PROXY` environment variable in the cert-manager pod | | +| `webhook.replicaCount` | Number of cert-manager webhook replicas | `1` | +| `webhook.timeoutSeconds` | Seconds the API server should wait the webhook to respond before treating the call as a failure. | `10` | +| `webhook.podAnnotations` | Annotations to add to the webhook pods | `{}` | +| `webhook.podLabels` | Labels to add to the cert-manager webhook pod | `{}` | +| `webhook.serviceLabels` | Labels to add to the cert-manager webhook service | `{}` | +| `webhook.deploymentAnnotations` | Annotations to add to the webhook deployment | `{}` | +| `webhook.mutatingWebhookConfigurationAnnotations` | Annotations to add to the mutating webhook configuration | `{}` | +| `webhook.validatingWebhookConfigurationAnnotations` | Annotations to add to the validating webhook configuration | `{}` | +| `webhook.serviceAnnotations` | Annotations to add to the webhook service | `{}` | +| `webhook.config` | WebhookConfiguration YAML used to configure flags for the webhook. Generates a ConfigMap containing contents of the field. See `values.yaml` for example. | `{}` | +| `webhook.extraArgs` | Optional flags for cert-manager webhook component | `[]` | +| `webhook.serviceAccount.create` | If `true`, create a new service account for the webhook component | `true` | +| `webhook.serviceAccount.name` | Service account for the webhook component to be used. If not set and `webhook.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `webhook.serviceAccount.annotations` | Annotations to add to the service account for the webhook component | | +| `webhook.serviceAccount.automountServiceAccountToken` | Automount API credentials for the webhook Service Account | | +| `webhook.resources` | CPU/memory resource requests/limits for the webhook pods | `{}` | +| `webhook.nodeSelector` | Node labels for webhook pod assignment | `{}` | +| `webhook.affinity` | Node affinity for webhook pod assignment | `{}` | +| `webhook.tolerations` | Node tolerations for webhook pod assignment | `[]` | +| `webhook.image.repository` | Webhook image repository | `quay.io/jetstack/cert-manager-webhook` | +| `webhook.image.tag` | Webhook image tag | `v1.8.1` | +| `webhook.image.pullPolicy` | Webhook image pull policy | `IfNotPresent` | +| `webhook.securePort` | The port that the webhook should listen on for requests. | `10250` | +| `webhook.securityContext` | Security context for webhook pod assignment | `{}` | +| `webhook.containerSecurityContext` | Security context to be set on the webhook component container | `{}` | +| `webhook.hostNetwork` | If `true`, run the Webhook on the host network. | `false` | +| `webhook.serviceType` | The type of the `Service`. | `ClusterIP` | +| `webhook.loadBalancerIP` | The specific load balancer IP to use (when `serviceType` is `LoadBalancer`). | | +| `webhook.url.host` | The host to use to reach the webhook, instead of using internal cluster DNS for the service. | | +| `webhook.livenessProbe.failureThreshold` | The liveness probe failure threshold | `3` | +| `webhook.livenessProbe.initialDelaySeconds` | The liveness probe initial delay (in seconds) | `60` | +| `webhook.livenessProbe.periodSeconds` | The liveness probe period (in seconds) | `10` | +| `webhook.livenessProbe.successThreshold` | The liveness probe success threshold | `1` | +| `webhook.livenessProbe.timeoutSeconds` | The liveness probe timeout (in seconds) | `1` | +| `webhook.readinessProbe.failureThreshold` | The readiness probe failure threshold | `3` | +| `webhook.readinessProbe.initialDelaySeconds` | The readiness probe initial delay (in seconds) | `5` | +| `webhook.readinessProbe.periodSeconds` | The readiness probe period (in seconds) | `5` | +| `webhook.readinessProbe.successThreshold` | The readiness probe success threshold | `1` | +| `webhook.readinessProbe.timeoutSeconds` | The readiness probe timeout (in seconds) | `1` | +| `cainjector.enabled` | Toggles whether the cainjector component should be installed (required for the webhook component to work) | `true` | +| `cainjector.replicaCount` | Number of cert-manager cainjector replicas | `1` | +| `cainjector.podAnnotations` | Annotations to add to the cainjector pods | `{}` | +| `cainjector.podLabels` | Labels to add to the cert-manager cainjector pod | `{}` | +| `cainjector.deploymentAnnotations` | Annotations to add to the cainjector deployment | `{}` | +| `cainjector.extraArgs` | Optional flags for cert-manager cainjector component | `[]` | +| `cainjector.serviceAccount.create` | If `true`, create a new service account for the cainjector component | `true` | +| `cainjector.serviceAccount.name` | Service account for the cainjector component to be used. If not set and `cainjector.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `cainjector.serviceAccount.annotations` | Annotations to add to the service account for the cainjector component | | +| `cainjector.serviceAccount.automountServiceAccountToken` | Automount API credentials for the cainjector Service Account | `true` | +| `cainjector.resources` | CPU/memory resource requests/limits for the cainjector pods | `{}` | +| `cainjector.nodeSelector` | Node labels for cainjector pod assignment | `{}` | +| `cainjector.affinity` | Node affinity for cainjector pod assignment | `{}` | +| `cainjector.tolerations` | Node tolerations for cainjector pod assignment | `[]` | +| `cainjector.image.repository` | cainjector image repository | `quay.io/jetstack/cert-manager-cainjector` | +| `cainjector.image.tag` | cainjector image tag | `v1.8.1` | +| `cainjector.image.pullPolicy` | cainjector image pull policy | `IfNotPresent` | +| `cainjector.securityContext` | Security context for cainjector pod assignment | `{}` | +| `cainjector.containerSecurityContext` | Security context to be set on cainjector component container | `{}` | +| `startupapicheck.enabled` | Toggles whether the startupapicheck Job should be installed | `true` | +| `startupapicheck.securityContext` | Pod Security Context to be set on the startupapicheck component Pod | `{}` | +| `startupapicheck.timeout` | Timeout for 'kubectl check api' command | `1m` | +| `startupapicheck.backoffLimit` | Job backoffLimit | `4` | +| `startupapicheck.jobAnnotations` | Optional additional annotations to add to the startupapicheck Job | `{}` | +| `startupapicheck.podAnnotations` | Optional additional annotations to add to the startupapicheck Pods | `{}` | +| `startupapicheck.extraArgs` | Optional additional arguments for startupapicheck | `[]` | +| `startupapicheck.resources` | CPU/memory resource requests/limits for the startupapicheck pod | `{}` | +| `startupapicheck.nodeSelector` | Node labels for startupapicheck pod assignment | `{}` | +| `startupapicheck.affinity` | Node affinity for startupapicheck pod assignment | `{}` | +| `startupapicheck.tolerations` | Node tolerations for startupapicheck pod assignment | `[]` | +| `startupapicheck.podLabels` | Optional additional labels to add to the startupapicheck Pods | `{}` | +| `startupapicheck.image.repository` | startupapicheck image repository | `quay.io/jetstack/cert-manager-ctl` | +| `startupapicheck.image.tag` | startupapicheck image tag | `v1.8.1` | +| `startupapicheck.image.pullPolicy` | startupapicheck image pull policy | `IfNotPresent` | +| `startupapicheck.serviceAccount.create` | If `true`, create a new service account for the startupapicheck component | `true` | +| `startupapicheck.serviceAccount.name` | Service account for the startupapicheck component to be used. If not set and `startupapicheck.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `startupapicheck.serviceAccount.annotations` | Annotations to add to the service account for the startupapicheck component | | +| `startupapicheck.serviceAccount.automountServiceAccountToken` | Automount API credentials for the startupapicheck Service Account | `true` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release -f values.yaml . +``` +> **Tip**: You can use the default [values.yaml](https://github.com/cert-manager/cert-manager/blob/master/deploy/charts/cert-manager/values.yaml) + +## Contributing + +This chart is maintained at [github.com/cert-manager/cert-manager](https://github.com/cert-manager/cert-manager/tree/master/deploy/charts/cert-manager). diff --git a/cert-manager/templates/NOTES.txt b/cert-manager/templates/NOTES.txt new file mode 100644 index 0000000..1025354 --- /dev/null +++ b/cert-manager/templates/NOTES.txt @@ -0,0 +1,15 @@ +cert-manager {{ .Chart.AppVersion }} has been deployed successfully! + +In order to begin issuing certificates, you will need to set up a ClusterIssuer +or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). + +More information on the different types of issuers and how to configure them +can be found in our documentation: + +https://cert-manager.io/docs/configuration/ + +For information on how to configure cert-manager to automatically provision +Certificates for Ingress resources, take a look at the `ingress-shim` +documentation: + +https://cert-manager.io/docs/usage/ingress/ diff --git a/cert-manager/templates/_helpers.tpl b/cert-manager/templates/_helpers.tpl new file mode 100644 index 0000000..2b6ee7f --- /dev/null +++ b/cert-manager/templates/_helpers.tpl @@ -0,0 +1,159 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "cert-manager.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). +*/}} +{{- define "cert-manager.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 the name of the service account to use +*/}} +{{- define "cert-manager.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "cert-manager.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Webhook templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'webhook' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "webhook.name" -}} +{{- printf "webhook" -}} +{{- 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 "webhook.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 55 | trimSuffix "-" -}} +{{- printf "%s-webhook" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "webhook.caRef" -}} +{{ .Release.Namespace }}/{{ template "webhook.fullname" . }}-ca +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "webhook.serviceAccountName" -}} +{{- if .Values.webhook.serviceAccount.create -}} + {{ default (include "webhook.fullname" .) .Values.webhook.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.webhook.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +cainjector templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'cainjector' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "cainjector.name" -}} +{{- printf "cainjector" -}} +{{- 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 "cainjector.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 52 | trimSuffix "-" -}} +{{- printf "%s-cainjector" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cainjector.serviceAccountName" -}} +{{- if .Values.cainjector.serviceAccount.create -}} + {{ default (include "cainjector.fullname" .) .Values.cainjector.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.cainjector.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +startupapicheck templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'startupapicheck' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "startupapicheck.name" -}} +{{- printf "startupapicheck" -}} +{{- 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 "startupapicheck.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 52 | trimSuffix "-" -}} +{{- printf "%s-startupapicheck" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "startupapicheck.serviceAccountName" -}} +{{- if .Values.startupapicheck.serviceAccount.create -}} + {{ default (include "startupapicheck.fullname" .) .Values.startupapicheck.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.startupapicheck.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chartName" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Labels that should be added on each resource +*/}} +{{- define "labels" -}} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- if eq (default "helm" .Values.creator) "helm" }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ include "chartName" . }} +{{- end -}} +{{- end -}} diff --git a/cert-manager/templates/cainjector-deployment.yaml b/cert-manager/templates/cainjector-deployment.yaml new file mode 100644 index 0000000..b617527 --- /dev/null +++ b/cert-manager/templates/cainjector-deployment.yaml @@ -0,0 +1,102 @@ +{{- if .Values.cainjector.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cainjector.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + {{- with .Values.cainjector.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.cainjector.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- with .Values.cainjector.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 8 }} + {{- with .Values.cainjector.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "cainjector.serviceAccountName" . }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.cainjector.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.cainjector.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.cainjector.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- with .Values.global.leaderElection }} + - --leader-election-namespace={{ .namespace }} + {{- if .leaseDuration }} + - --leader-election-lease-duration={{ .leaseDuration }} + {{- end }} + {{- if .renewDeadline }} + - --leader-election-renew-deadline={{ .renewDeadline }} + {{- end }} + {{- if .retryPeriod }} + - --leader-election-retry-period={{ .retryPeriod }} + {{- end }} + {{- end }} + {{- with .Values.cainjector.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.cainjector.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.cainjector.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.cainjector.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/cert-manager/templates/cainjector-psp-clusterrole.yaml b/cert-manager/templates/cainjector-psp-clusterrole.yaml new file mode 100644 index 0000000..b75b9eb --- /dev/null +++ b/cert-manager/templates/cainjector-psp-clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cainjector.fullname" . }}-psp + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "cainjector.fullname" . }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml b/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml new file mode 100644 index 0000000..b287802 --- /dev/null +++ b/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml @@ -0,0 +1,22 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cainjector.fullname" . }}-psp + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cainjector.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/cainjector-psp.yaml b/cert-manager/templates/cainjector-psp.yaml new file mode 100644 index 0000000..24f01da --- /dev/null +++ b/cert-manager/templates/cainjector-psp.yaml @@ -0,0 +1,51 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} +{{- end }} diff --git a/cert-manager/templates/cainjector-rbac.yaml b/cert-manager/templates/cainjector-rbac.yaml new file mode 100644 index 0000000..6cb396e --- /dev/null +++ b/cert-manager/templates/cainjector-rbac.yaml @@ -0,0 +1,103 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "create", "update", "patch"] + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["apiregistration.k8s.io"] + resources: ["apiservices"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cainjector.fullname" . }} +subjects: + - name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- +# leader election rules +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "cainjector.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: + # Used for leader election by the controller + # cert-manager-cainjector-leader-election is used by the CertificateBased injector controller + # see cmd/cainjector/start.go#L113 + # cert-manager-cainjector-leader-election-core is used by the SecretBased injector controller + # see cmd/cainjector/start.go#L137 + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + resourceNames: ["cert-manager-cainjector-leader-election", "cert-manager-cainjector-leader-election-core"] + verbs: ["get", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] + +--- + +# grant cert-manager permission to manage the leaderelection configmap in the +# leader election namespace +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "cainjector.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "cainjector.fullname" . }}:leaderelection +subjects: + - kind: ServiceAccount + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/cainjector-serviceaccount.yaml b/cert-manager/templates/cainjector-serviceaccount.yaml new file mode 100644 index 0000000..6457b9e --- /dev/null +++ b/cert-manager/templates/cainjector-serviceaccount.yaml @@ -0,0 +1,27 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.cainjector.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.cainjector.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + {{- with .Values.cainjector.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + {{- with .Values.cainjector.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/crds.yaml b/cert-manager/templates/crds.yaml new file mode 100644 index 0000000..afea0de --- /dev/null +++ b/cert-manager/templates/crds.yaml @@ -0,0 +1,4280 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: certificaterequests.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: CertificateRequest + listKind: CertificateRequestList + plural: certificaterequests + shortNames: + - cr + - crs + singular: certificaterequest + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Approved")].status + name: Approved + type: string + - jsonPath: .status.conditions[?(@.type=="Denied")].status + name: Denied + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + type: string + - jsonPath: .spec.username + name: Requestor + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: "A CertificateRequest is used to request a signed certificate from one of the configured issuers. \n All fields within the CertificateRequest's `spec` are immutable after creation. A CertificateRequest will either succeed or fail, as denoted by its `status.state` field. \n A CertificateRequest is a one-shot resource, meaning it represents a single point in time request for a certificate and cannot be re-used." + type: object + required: + - spec + 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: Desired state of the CertificateRequest resource. + type: object + required: + - issuerRef + - request + properties: + duration: + description: The requested 'duration' (i.e. lifetime) of the Certificate. This option may be ignored/overridden by some issuer types. + type: string + extra: + description: Extra contains extra attributes of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: object + additionalProperties: + type: array + items: + type: string + groups: + description: Groups contains group membership of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: array + items: + type: string + x-kubernetes-list-type: atomic + isCA: + description: IsCA will request to mark the certificate as valid for certificate signing when submitting to the issuer. This will automatically add the `cert sign` usage to the list of `usages`. + type: boolean + issuerRef: + description: IssuerRef is a reference to the issuer for this CertificateRequest. If the `kind` field is not set, or set to `Issuer`, an Issuer resource with the given name in the same namespace as the CertificateRequest will be used. If the `kind` field is set to `ClusterIssuer`, a ClusterIssuer with the provided name will be used. The `name` field in this stanza is required at all times. The group field refers to the API group of the issuer which defaults to `cert-manager.io` if empty. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + request: + description: The PEM-encoded x509 certificate signing request to be submitted to the CA for signing. + type: string + format: byte + uid: + description: UID contains the uid of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: string + usages: + description: Usages is the set of x509 usages that are requested for the certificate. If usages are set they SHOULD be encoded inside the CSR spec Defaults to `digital signature` and `key encipherment` if not specified. + type: array + items: + description: 'KeyUsage specifies valid usage contexts for keys. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 https://tools.ietf.org/html/rfc5280#section-4.2.1.12 Valid KeyUsage values are as follows: "signing", "digital signature", "content commitment", "key encipherment", "key agreement", "data encipherment", "cert sign", "crl sign", "encipher only", "decipher only", "any", "server auth", "client auth", "code signing", "email protection", "s/mime", "ipsec end system", "ipsec tunnel", "ipsec user", "timestamping", "ocsp signing", "microsoft sgc", "netscape sgc"' + type: string + enum: + - signing + - digital signature + - content commitment + - key encipherment + - key agreement + - data encipherment + - cert sign + - crl sign + - encipher only + - decipher only + - any + - server auth + - client auth + - code signing + - email protection + - s/mime + - ipsec end system + - ipsec tunnel + - ipsec user + - timestamping + - ocsp signing + - microsoft sgc + - netscape sgc + username: + description: Username contains the name of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: string + status: + description: Status of the CertificateRequest. This is set and managed automatically. + type: object + properties: + ca: + description: The PEM encoded x509 certificate of the signer, also known as the CA (Certificate Authority). This is set on a best-effort basis by different issuers. If not set, the CA is assumed to be unknown/not available. + type: string + format: byte + certificate: + description: The PEM encoded x509 certificate resulting from the certificate signing request. If not set, the CertificateRequest has either not been completed or has failed. More information on failure can be found by checking the `conditions` field. + type: string + format: byte + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready` and `InvalidRequest`. + type: array + items: + description: CertificateRequestCondition contains condition information for a CertificateRequest. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`, `InvalidRequest`, `Approved`, `Denied`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + failureTime: + description: FailureTime stores the time that this CertificateRequest failed. This is used to influence garbage collection and back-off. + type: string + format: date-time + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: certificates.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: Certificate + listKind: CertificateList + plural: certificates + shortNames: + - cert + - certs + singular: certificate + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .spec.secretName + name: Secret + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: "A Certificate resource should be created to ensure an up to date and signed x509 certificate is stored in the Kubernetes Secret resource named in `spec.secretName`. \n The stored certificate will be renewed before it expires (as configured by `spec.renewBefore`)." + type: object + required: + - spec + 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: Desired state of the Certificate resource. + type: object + required: + - issuerRef + - secretName + properties: + additionalOutputFormats: + description: AdditionalOutputFormats defines extra output formats of the private key and signed certificate chain to be written to this Certificate's target Secret. This is an Alpha Feature and is only enabled with the `--feature-gates=AdditionalCertificateOutputFormats=true` option on both the controller and webhook components. + type: array + items: + description: CertificateAdditionalOutputFormat defines an additional output format of a Certificate resource. These contain supplementary data formats of the signed certificate chain and paired private key. + type: object + required: + - type + properties: + type: + description: Type is the name of the format type that should be written to the Certificate's target Secret. + type: string + enum: + - DER + - CombinedPEM + commonName: + description: 'CommonName is a common name to be used on the Certificate. The CommonName should have a length of 64 characters or fewer to avoid generating invalid CSRs. This value is ignored by TLS clients when any subject alt name is set. This is x509 behaviour: https://tools.ietf.org/html/rfc6125#section-6.4.4' + type: string + dnsNames: + description: DNSNames is a list of DNS subjectAltNames to be set on the Certificate. + type: array + items: + type: string + duration: + description: The requested 'duration' (i.e. lifetime) of the Certificate. This option may be ignored/overridden by some issuer types. If unset this defaults to 90 days. Certificate will be renewed either 2/3 through its duration or `renewBefore` period before its expiry, whichever is later. Minimum accepted duration is 1 hour. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + emailAddresses: + description: EmailAddresses is a list of email subjectAltNames to be set on the Certificate. + type: array + items: + type: string + encodeUsagesInRequest: + description: EncodeUsagesInRequest controls whether key usages should be present in the CertificateRequest + type: boolean + ipAddresses: + description: IPAddresses is a list of IP address subjectAltNames to be set on the Certificate. + type: array + items: + type: string + isCA: + description: IsCA will mark this Certificate as valid for certificate signing. This will automatically add the `cert sign` usage to the list of `usages`. + type: boolean + issuerRef: + description: IssuerRef is a reference to the issuer for this certificate. If the `kind` field is not set, or set to `Issuer`, an Issuer resource with the given name in the same namespace as the Certificate will be used. If the `kind` field is set to `ClusterIssuer`, a ClusterIssuer with the provided name will be used. The `name` field in this stanza is required at all times. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + keystores: + description: Keystores configures additional keystore output formats stored in the `secretName` Secret resource. + type: object + properties: + jks: + description: JKS configures options for storing a JKS keystore in the `spec.secretName` Secret resource. + type: object + required: + - create + - passwordSecretRef + properties: + create: + description: Create enables JKS keystore creation for the Certificate. If true, a file named `keystore.jks` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will only be updated upon re-issuance. A file named `truststore.jks` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority + type: boolean + passwordSecretRef: + description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the JKS keystore. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + pkcs12: + description: PKCS12 configures options for storing a PKCS12 keystore in the `spec.secretName` Secret resource. + type: object + required: + - create + - passwordSecretRef + properties: + create: + description: Create enables PKCS12 keystore creation for the Certificate. If true, a file named `keystore.p12` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will only be updated upon re-issuance. A file named `truststore.p12` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority + type: boolean + passwordSecretRef: + description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the PKCS12 keystore. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + privateKey: + description: Options to control private keys used for the Certificate. + type: object + properties: + algorithm: + description: Algorithm is the private key algorithm of the corresponding private key for this certificate. If provided, allowed values are either `RSA`,`Ed25519` or `ECDSA` If `algorithm` is specified and `size` is not provided, key size of 256 will be used for `ECDSA` key algorithm and key size of 2048 will be used for `RSA` key algorithm. key size is ignored when using the `Ed25519` key algorithm. + type: string + enum: + - RSA + - ECDSA + - Ed25519 + encoding: + description: The private key cryptography standards (PKCS) encoding for this certificate's private key to be encoded in. If provided, allowed values are `PKCS1` and `PKCS8` standing for PKCS#1 and PKCS#8, respectively. Defaults to `PKCS1` if not specified. + type: string + enum: + - PKCS1 + - PKCS8 + rotationPolicy: + description: RotationPolicy controls how private keys should be regenerated when a re-issuance is being processed. If set to Never, a private key will only be generated if one does not already exist in the target `spec.secretName`. If one does exists but it does not have the correct algorithm or size, a warning will be raised to await user intervention. If set to Always, a private key matching the specified requirements will be generated whenever a re-issuance occurs. Default is 'Never' for backward compatibility. + type: string + enum: + - Never + - Always + size: + description: Size is the key bit size of the corresponding private key for this certificate. If `algorithm` is set to `RSA`, valid values are `2048`, `4096` or `8192`, and will default to `2048` if not specified. If `algorithm` is set to `ECDSA`, valid values are `256`, `384` or `521`, and will default to `256` if not specified. If `algorithm` is set to `Ed25519`, Size is ignored. No other values are allowed. + type: integer + renewBefore: + description: How long before the currently issued certificate's expiry cert-manager should renew the certificate. The default is 2/3 of the issued certificate's duration. Minimum accepted value is 5 minutes. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + revisionHistoryLimit: + description: revisionHistoryLimit is the maximum number of CertificateRequest revisions that are maintained in the Certificate's history. Each revision represents a single `CertificateRequest` created by this Certificate, either when it was created, renewed, or Spec was changed. Revisions will be removed by oldest first if the number of revisions exceeds this number. If set, revisionHistoryLimit must be a value of `1` or greater. If unset (`nil`), revisions will not be garbage collected. Default value is `nil`. + type: integer + format: int32 + secretName: + description: SecretName is the name of the secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer. + type: string + secretTemplate: + description: SecretTemplate defines annotations and labels to be copied to the Certificate's Secret. Labels and annotations on the Secret will be changed as they appear on the SecretTemplate when added or removed. SecretTemplate annotations are added in conjunction with, and cannot overwrite, the base set of annotations cert-manager sets on the Certificate's Secret. + type: object + properties: + annotations: + description: Annotations is a key value map to be copied to the target Kubernetes Secret. + type: object + additionalProperties: + type: string + labels: + description: Labels is a key value map to be copied to the target Kubernetes Secret. + type: object + additionalProperties: + type: string + subject: + description: Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name). + type: object + properties: + countries: + description: Countries to be used on the Certificate. + type: array + items: + type: string + localities: + description: Cities to be used on the Certificate. + type: array + items: + type: string + organizationalUnits: + description: Organizational Units to be used on the Certificate. + type: array + items: + type: string + organizations: + description: Organizations to be used on the Certificate. + type: array + items: + type: string + postalCodes: + description: Postal codes to be used on the Certificate. + type: array + items: + type: string + provinces: + description: State/Provinces to be used on the Certificate. + type: array + items: + type: string + serialNumber: + description: Serial number to be used on the Certificate. + type: string + streetAddresses: + description: Street addresses to be used on the Certificate. + type: array + items: + type: string + uris: + description: URIs is a list of URI subjectAltNames to be set on the Certificate. + type: array + items: + type: string + usages: + description: Usages is the set of x509 usages that are requested for the certificate. Defaults to `digital signature` and `key encipherment` if not specified. + type: array + items: + description: 'KeyUsage specifies valid usage contexts for keys. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 https://tools.ietf.org/html/rfc5280#section-4.2.1.12 Valid KeyUsage values are as follows: "signing", "digital signature", "content commitment", "key encipherment", "key agreement", "data encipherment", "cert sign", "crl sign", "encipher only", "decipher only", "any", "server auth", "client auth", "code signing", "email protection", "s/mime", "ipsec end system", "ipsec tunnel", "ipsec user", "timestamping", "ocsp signing", "microsoft sgc", "netscape sgc"' + type: string + enum: + - signing + - digital signature + - content commitment + - key encipherment + - key agreement + - data encipherment + - cert sign + - crl sign + - encipher only + - decipher only + - any + - server auth + - client auth + - code signing + - email protection + - s/mime + - ipsec end system + - ipsec tunnel + - ipsec user + - timestamping + - ocsp signing + - microsoft sgc + - netscape sgc + status: + description: Status of the Certificate. This is set and managed automatically. + type: object + properties: + conditions: + description: List of status conditions to indicate the status of certificates. Known condition types are `Ready` and `Issuing`. + type: array + items: + description: CertificateCondition contains condition information for an Certificate. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Certificate. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`, `Issuing`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + failedIssuanceAttempts: + description: The number of continuous failed issuance attempts up till now. This field gets removed (if set) on a successful issuance and gets set to 1 if unset and an issuance has failed. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1). + type: integer + lastFailureTime: + description: LastFailureTime is the time as recorded by the Certificate controller of the most recent failure to complete a CertificateRequest for this Certificate resource. If set, cert-manager will not re-request another Certificate until 1 hour has elapsed from this time. + type: string + format: date-time + nextPrivateKeySecretName: + description: The name of the Secret resource containing the private key to be used for the next certificate iteration. The keymanager controller will automatically set this field if the `Issuing` condition is set to `True`. It will automatically unset this field when the Issuing condition is not set or False. + type: string + notAfter: + description: The expiration time of the certificate stored in the secret named by this resource in `spec.secretName`. + type: string + format: date-time + notBefore: + description: The time after which the certificate stored in the secret named by this resource in spec.secretName is valid. + type: string + format: date-time + renewalTime: + description: RenewalTime is the time at which the certificate will be next renewed. If not set, no upcoming renewal is scheduled. + type: string + format: date-time + revision: + description: "The current 'revision' of the certificate as issued. \n When a CertificateRequest resource is created, it will have the `cert-manager.io/certificate-revision` set to one greater than the current value of this field. \n Upon issuance, this field will be set to the value of the annotation on the CertificateRequest resource used to issue the certificate. \n Persisting the value on the CertificateRequest resource allows the certificates controller to know whether a request is part of an old issuance or if it is part of the ongoing revision's issuance by checking if the revision value in the annotation is greater than this field." + type: integer + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: challenges.acme.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: acme.cert-manager.io + names: + kind: Challenge + listKind: ChallengeList + plural: challenges + singular: challenge + categories: + - cert-manager + - cert-manager-acme + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .spec.dnsName + name: Domain + type: string + - jsonPath: .status.reason + name: Reason + priority: 1 + type: string + - description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Challenge is a type to represent a Challenge request with an ACME server + type: object + required: + - metadata + - spec + 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: + type: object + required: + - authorizationURL + - dnsName + - issuerRef + - key + - solver + - token + - type + - url + properties: + authorizationURL: + description: The URL to the ACME Authorization resource that this challenge is a part of. + type: string + dnsName: + description: dnsName is the identifier that this challenge is for, e.g. example.com. If the requested DNSName is a 'wildcard', this field MUST be set to the non-wildcard domain, e.g. for `*.example.com`, it must be `example.com`. + type: string + issuerRef: + description: References a properly configured ACME-type Issuer which should be used to create this Challenge. If the Issuer does not exist, processing will be retried. If the Issuer is not an 'ACME' Issuer, an error will be returned and the Challenge will be marked as failed. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + key: + description: 'The ACME challenge key for this challenge For HTTP01 challenges, this is the value that must be responded with to complete the HTTP01 challenge in the format: `.`. For DNS01 challenges, this is the base64 encoded SHA256 sum of the `.` text that must be set as the TXT record content.' + type: string + solver: + description: Contains the domain solving configuration that should be used to solve this challenge resource. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentRef identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) Support: Custom (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: The ingress class to use when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of 'class' or 'name' may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Only the 'priorityClassName', 'nodeSelector', 'affinity', 'serviceAccountName' and 'tolerations' fields are supported currently. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + token: + description: The ACME challenge token for this challenge. This is the raw value returned from the ACME server. + type: string + type: + description: The type of ACME challenge this resource represents. One of "HTTP-01" or "DNS-01". + type: string + enum: + - HTTP-01 + - DNS-01 + url: + description: The URL of the ACME Challenge resource for this challenge. This can be used to lookup details about the status of this challenge. + type: string + wildcard: + description: wildcard will be true if this challenge is for a wildcard identifier, for example '*.example.com'. + type: boolean + status: + type: object + properties: + presented: + description: presented will be set to true if the challenge values for this challenge are currently 'presented'. This *does not* imply the self check is passing. Only that the values have been 'submitted' for the appropriate challenge mechanism (i.e. the DNS01 TXT record has been presented, or the HTTP01 configuration has been configured). + type: boolean + processing: + description: Used to denote whether this challenge should be processed or not. This field will only be set to true by the 'scheduling' component. It will only be set to false by the 'challenges' controller, after the challenge has reached a final state or timed out. If this field is set to false, the challenge controller will not take any more action. + type: boolean + reason: + description: Contains human readable information on why the Challenge is in the current state. + type: string + state: + description: Contains the current 'state' of the challenge. If not set, the state of the challenge is unknown. + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterissuers.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: ClusterIssuer + listKind: ClusterIssuerList + plural: clusterissuers + singular: clusterissuer + categories: + - cert-manager + scope: Cluster + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: A ClusterIssuer represents a certificate issuing authority which can be referenced as part of `issuerRef` fields. It is similar to an Issuer, however it is cluster-scoped and therefore can be referenced by resources that exist in *any* namespace, not just the same namespace as the referent. + type: object + required: + - spec + 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: Desired state of the ClusterIssuer resource. + type: object + properties: + acme: + description: ACME configures this issuer to communicate with a RFC8555 (ACME) server to obtain signed x509 certificates. + type: object + required: + - privateKeySecretRef + - server + properties: + disableAccountKeyGeneration: + description: Enables or disables generating a new ACME account key. If true, the Issuer resource will *not* request a new account but will expect the account key to be supplied via an existing secret. If false, the cert-manager system will generate a new ACME account key for the Issuer. Defaults to false. + type: boolean + email: + description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered. + type: string + enableDurationFeature: + description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false. + type: boolean + externalAccountBinding: + description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account. + type: object + required: + - keyID + - keySecretRef + properties: + keyAlgorithm: + description: 'Deprecated: keyAlgorithm field exists for historical compatibility reasons and should not be used. The algorithm is now hardcoded to HS256 in golang/x/crypto/acme.' + type: string + enum: + - HS256 + - HS384 + - HS512 + keyID: + description: keyID is the ID of the CA key that the External Account is bound to. + type: string + keySecretRef: + description: keySecretRef is a Secret Key Selector referencing a data item in a Kubernetes Secret which holds the symmetric MAC key of the External Account Binding. The `key` is the index string that is paired with the key data in the Secret and should not be confused with the key data itself, or indeed with the External Account Binding keyID above. The secret key stored in the Secret **must** be un-padded, base64 URL encoded data. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + preferredChain: + description: 'PreferredChain is the chain to use if the ACME server outputs multiple. PreferredChain is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let''s Encrypt''s DST crosssign you would use: "DST Root CA X3" or "ISRG Root X1" for the newer Let''s Encrypt root CA. This value picks the first certificate bundle in the ACME alternative chains that has a certificate with this value as its issuer''s CN' + type: string + maxLength: 64 + privateKeySecretRef: + description: PrivateKey is the name of a Kubernetes Secret resource that will be used to store the automatically generated ACME account private key. Optionally, a `key` may be specified to select a specific entry within the named Secret resource. If `key` is not specified, a default of `tls.key` will be used. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + server: + description: 'Server is the URL used to access the ACME server''s ''directory'' endpoint. For example, for Let''s Encrypt''s staging endpoint, you would use: "https://acme-staging-v02.api.letsencrypt.org/directory". Only ACME v2 endpoints (i.e. RFC 8555) are supported.' + type: string + skipTLSVerify: + description: Enables or disables validation of the ACME server TLS certificate. If true, requests to the ACME server will not have their TLS certificate validated (i.e. insecure connections will be allowed). Only enable this option in development environments. The cert-manager system installed roots will be used to verify connections to the ACME server if this is false. Defaults to false. + type: boolean + solvers: + description: 'Solvers is a list of challenge solvers that will be used to solve ACME challenges for the matching domains. Solver configurations must be provided in order to obtain certificates from an ACME server. For more information, see: https://cert-manager.io/docs/configuration/acme/' + type: array + items: + description: An ACMEChallengeSolver describes how to solve ACME challenges for the issuer it is part of. A selector may be provided to use different solving strategies for different DNS names. Only one of HTTP01 or DNS01 must be provided. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentRef identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) Support: Custom (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: The ingress class to use when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of 'class' or 'name' may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Only the 'priorityClassName', 'nodeSelector', 'affinity', 'serviceAccountName' and 'tolerations' fields are supported currently. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + ca: + description: CA configures this issuer to sign certificates using a signing CA keypair stored in a Secret resource. This is used to build internal PKIs that are managed by cert-manager. + type: object + required: + - secretName + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set, certificates will be issued without distribution points set. + type: array + items: + type: string + ocspServers: + description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". + type: array + items: + type: string + secretName: + description: SecretName is the name of the secret used to sign Certificates issued by this Issuer. + type: string + selfSigned: + description: SelfSigned configures this issuer to 'self sign' certificates using the private key used to create the CertificateRequest object. + type: object + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set certificate will be issued without CDP. Values are strings. + type: array + items: + type: string + vault: + description: Vault configures this issuer to sign certificates using a HashiCorp Vault PKI backend. + type: object + required: + - auth + - path + - server + properties: + auth: + description: Auth configures how cert-manager authenticates with the Vault server. + type: object + properties: + appRole: + description: AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource. + type: object + required: + - path + - roleId + - secretRef + properties: + path: + description: 'Path where the App Role authentication backend is mounted in Vault, e.g: "approle"' + type: string + roleId: + description: RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault. + type: string + secretRef: + description: Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The `key` field must be specified and denotes which entry within the Secret resource is used as the app role secret. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + kubernetes: + description: Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server. + type: object + required: + - role + - secretRef + properties: + mountPath: + description: The Vault mountPath here is the mount path to use when authenticating with Vault. For example, setting a value to `/v1/auth/foo`, will use the path `/v1/auth/foo/login` to authenticate with Vault. If unspecified, the default value "/v1/auth/kubernetes" will be used. + type: string + role: + description: A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of 'ambient credentials' is not supported. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + caBundle: + description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. + type: string + format: byte + namespace: + description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' + type: string + path: + description: 'Path is the mount path of the Vault PKI backend''s `sign` endpoint, e.g: "my_pki_mount/sign/my-role-name".' + type: string + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + venafi: + description: Venafi configures this issuer to sign certificates using a Venafi TPP or Venafi Cloud policy zone. + type: object + required: + - zone + properties: + cloud: + description: Cloud specifies the Venafi cloud configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - apiTokenSecretRef + properties: + apiTokenSecretRef: + description: APITokenSecretRef is a secret key selector for the Venafi Cloud API token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: URL is the base URL for Venafi Cloud. Defaults to "https://api.venafi.cloud/v1". + type: string + tpp: + description: TPP specifies Trust Protection Platform configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - credentialsRef + - url + properties: + caBundle: + description: CABundle is a PEM encoded TLS certificate to use to verify connections to the TPP instance. If specified, system roots will not be used and the issuing CA for the TPP instance must be verifiable using the provided root. If not specified, the connection will be verified using the cert-manager system root certificates. + type: string + format: byte + credentialsRef: + description: CredentialsRef is a reference to a Secret containing the username and password for the TPP server. The secret must contain two keys, 'username' and 'password'. + type: object + required: + - name + properties: + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: 'URL is the base URL for the vedsdk endpoint of the Venafi TPP instance, for example: "https://tpp.example.com/vedsdk".' + type: string + zone: + description: Zone is the Venafi Policy Zone to use for this issuer. All requests made to the Venafi platform will be restricted by the named zone policy. This field is required. + type: string + status: + description: Status of the ClusterIssuer. This is set and managed automatically. + type: object + properties: + acme: + description: ACME specific status options. This field should only be set if the Issuer is configured to use an ACME server to issue certificates. + type: object + properties: + lastRegisteredEmail: + description: LastRegisteredEmail is the email associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + uri: + description: URI is the unique account identifier, which can also be used to retrieve account details from the CA + type: string + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready`. + type: array + items: + description: IssuerCondition contains condition information for an Issuer. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Issuer. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: issuers.cert-manager.io + annotations: + cert-manager.io/inject-ca-from-secret: '{{ template "webhook.caRef" . }}' + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: Issuer + listKind: IssuerList + plural: issuers + singular: issuer + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: An Issuer represents a certificate issuing authority which can be referenced as part of `issuerRef` fields. It is scoped to a single namespace and can therefore only be referenced by resources within the same namespace. + type: object + required: + - spec + 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: Desired state of the Issuer resource. + type: object + properties: + acme: + description: ACME configures this issuer to communicate with a RFC8555 (ACME) server to obtain signed x509 certificates. + type: object + required: + - privateKeySecretRef + - server + properties: + disableAccountKeyGeneration: + description: Enables or disables generating a new ACME account key. If true, the Issuer resource will *not* request a new account but will expect the account key to be supplied via an existing secret. If false, the cert-manager system will generate a new ACME account key for the Issuer. Defaults to false. + type: boolean + email: + description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered. + type: string + enableDurationFeature: + description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false. + type: boolean + externalAccountBinding: + description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account. + type: object + required: + - keyID + - keySecretRef + properties: + keyAlgorithm: + description: 'Deprecated: keyAlgorithm field exists for historical compatibility reasons and should not be used. The algorithm is now hardcoded to HS256 in golang/x/crypto/acme.' + type: string + enum: + - HS256 + - HS384 + - HS512 + keyID: + description: keyID is the ID of the CA key that the External Account is bound to. + type: string + keySecretRef: + description: keySecretRef is a Secret Key Selector referencing a data item in a Kubernetes Secret which holds the symmetric MAC key of the External Account Binding. The `key` is the index string that is paired with the key data in the Secret and should not be confused with the key data itself, or indeed with the External Account Binding keyID above. The secret key stored in the Secret **must** be un-padded, base64 URL encoded data. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + preferredChain: + description: 'PreferredChain is the chain to use if the ACME server outputs multiple. PreferredChain is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let''s Encrypt''s DST crosssign you would use: "DST Root CA X3" or "ISRG Root X1" for the newer Let''s Encrypt root CA. This value picks the first certificate bundle in the ACME alternative chains that has a certificate with this value as its issuer''s CN' + type: string + maxLength: 64 + privateKeySecretRef: + description: PrivateKey is the name of a Kubernetes Secret resource that will be used to store the automatically generated ACME account private key. Optionally, a `key` may be specified to select a specific entry within the named Secret resource. If `key` is not specified, a default of `tls.key` will be used. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + server: + description: 'Server is the URL used to access the ACME server''s ''directory'' endpoint. For example, for Let''s Encrypt''s staging endpoint, you would use: "https://acme-staging-v02.api.letsencrypt.org/directory". Only ACME v2 endpoints (i.e. RFC 8555) are supported.' + type: string + skipTLSVerify: + description: Enables or disables validation of the ACME server TLS certificate. If true, requests to the ACME server will not have their TLS certificate validated (i.e. insecure connections will be allowed). Only enable this option in development environments. The cert-manager system installed roots will be used to verify connections to the ACME server if this is false. Defaults to false. + type: boolean + solvers: + description: 'Solvers is a list of challenge solvers that will be used to solve ACME challenges for the matching domains. Solver configurations must be provided in order to obtain certificates from an ACME server. For more information, see: https://cert-manager.io/docs/configuration/acme/' + type: array + items: + description: An ACMEChallengeSolver describes how to solve ACME challenges for the issuer it is part of. A selector may be provided to use different solving strategies for different DNS names. Only one of HTTP01 or DNS01 must be provided. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication. If not set we fall-back to using env vars, shared credentials file or AWS Instance metadata https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentRef identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) Support: Custom (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: The ingress class to use when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of 'class' or 'name' may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Only the 'priorityClassName', 'nodeSelector', 'affinity', 'serviceAccountName' and 'tolerations' fields are supported currently. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + ca: + description: CA configures this issuer to sign certificates using a signing CA keypair stored in a Secret resource. This is used to build internal PKIs that are managed by cert-manager. + type: object + required: + - secretName + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set, certificates will be issued without distribution points set. + type: array + items: + type: string + ocspServers: + description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". + type: array + items: + type: string + secretName: + description: SecretName is the name of the secret used to sign Certificates issued by this Issuer. + type: string + selfSigned: + description: SelfSigned configures this issuer to 'self sign' certificates using the private key used to create the CertificateRequest object. + type: object + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set certificate will be issued without CDP. Values are strings. + type: array + items: + type: string + vault: + description: Vault configures this issuer to sign certificates using a HashiCorp Vault PKI backend. + type: object + required: + - auth + - path + - server + properties: + auth: + description: Auth configures how cert-manager authenticates with the Vault server. + type: object + properties: + appRole: + description: AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource. + type: object + required: + - path + - roleId + - secretRef + properties: + path: + description: 'Path where the App Role authentication backend is mounted in Vault, e.g: "approle"' + type: string + roleId: + description: RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault. + type: string + secretRef: + description: Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The `key` field must be specified and denotes which entry within the Secret resource is used as the app role secret. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + kubernetes: + description: Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server. + type: object + required: + - role + - secretRef + properties: + mountPath: + description: The Vault mountPath here is the mount path to use when authenticating with Vault. For example, setting a value to `/v1/auth/foo`, will use the path `/v1/auth/foo/login` to authenticate with Vault. If unspecified, the default value "/v1/auth/kubernetes" will be used. + type: string + role: + description: A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of 'ambient credentials' is not supported. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + caBundle: + description: PEM-encoded CA bundle (base64-encoded) used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection. + type: string + format: byte + namespace: + description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' + type: string + path: + description: 'Path is the mount path of the Vault PKI backend''s `sign` endpoint, e.g: "my_pki_mount/sign/my-role-name".' + type: string + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + venafi: + description: Venafi configures this issuer to sign certificates using a Venafi TPP or Venafi Cloud policy zone. + type: object + required: + - zone + properties: + cloud: + description: Cloud specifies the Venafi cloud configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - apiTokenSecretRef + properties: + apiTokenSecretRef: + description: APITokenSecretRef is a secret key selector for the Venafi Cloud API token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: URL is the base URL for Venafi Cloud. Defaults to "https://api.venafi.cloud/v1". + type: string + tpp: + description: TPP specifies Trust Protection Platform configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - credentialsRef + - url + properties: + caBundle: + description: CABundle is a PEM encoded TLS certificate to use to verify connections to the TPP instance. If specified, system roots will not be used and the issuing CA for the TPP instance must be verifiable using the provided root. If not specified, the connection will be verified using the cert-manager system root certificates. + type: string + format: byte + credentialsRef: + description: CredentialsRef is a reference to a Secret containing the username and password for the TPP server. The secret must contain two keys, 'username' and 'password'. + type: object + required: + - name + properties: + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: 'URL is the base URL for the vedsdk endpoint of the Venafi TPP instance, for example: "https://tpp.example.com/vedsdk".' + type: string + zone: + description: Zone is the Venafi Policy Zone to use for this issuer. All requests made to the Venafi platform will be restricted by the named zone policy. This field is required. + type: string + status: + description: Status of the Issuer. This is set and managed automatically. + type: object + properties: + acme: + description: ACME specific status options. This field should only be set if the Issuer is configured to use an ACME server to issue certificates. + type: object + properties: + lastRegisteredEmail: + description: LastRegisteredEmail is the email associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + uri: + description: URI is the unique account identifier, which can also be used to retrieve account details from the CA + type: string + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready`. + type: array + items: + description: IssuerCondition contains condition information for an Issuer. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Issuer. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: orders.acme.cert-manager.io + annotations: + cert-manager.io/inject-ca-from-secret: '{{ template "webhook.caRef" . }}' + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: acme.cert-manager.io + names: + kind: Order + listKind: OrderList + plural: orders + singular: order + categories: + - cert-manager + - cert-manager-acme + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + priority: 1 + type: string + - jsonPath: .status.reason + name: Reason + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: Order is a type to represent an Order with an ACME server + type: object + required: + - metadata + - spec + 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: + type: object + required: + - issuerRef + - request + properties: + commonName: + description: CommonName is the common name as specified on the DER encoded CSR. If specified, this value must also be present in `dnsNames` or `ipAddresses`. This field must match the corresponding field on the DER encoded CSR. + type: string + dnsNames: + description: DNSNames is a list of DNS names that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR. + type: array + items: + type: string + duration: + description: Duration is the duration for the not after date for the requested certificate. this is set on order creation as pe the ACME spec. + type: string + ipAddresses: + description: IPAddresses is a list of IP addresses that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR. + type: array + items: + type: string + issuerRef: + description: IssuerRef references a properly configured ACME-type Issuer which should be used to create this Order. If the Issuer does not exist, processing will be retried. If the Issuer is not an 'ACME' Issuer, an error will be returned and the Order will be marked as failed. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + request: + description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order. + type: string + format: byte + status: + type: object + properties: + authorizations: + description: Authorizations contains data returned from the ACME server on what authorizations must be completed in order to validate the DNS names specified on the Order. + type: array + items: + description: ACMEAuthorization contains data returned from the ACME server on an authorization that must be completed in order validate a DNS name on an ACME Order resource. + type: object + required: + - url + properties: + challenges: + description: Challenges specifies the challenge types offered by the ACME server. One of these challenge types will be selected when validating the DNS name and an appropriate Challenge resource will be created to perform the ACME challenge process. + type: array + items: + description: Challenge specifies a challenge offered by the ACME server for an Order. An appropriate Challenge resource can be created to perform the ACME challenge process. + type: object + required: + - token + - type + - url + properties: + token: + description: Token is the token that must be presented for this challenge. This is used to compute the 'key' that must also be presented. + type: string + type: + description: Type is the type of challenge being offered, e.g. 'http-01', 'dns-01', 'tls-sni-01', etc. This is the raw value retrieved from the ACME server. Only 'http-01' and 'dns-01' are supported by cert-manager, other values will be ignored. + type: string + url: + description: URL is the URL of this challenge. It can be used to retrieve additional metadata about the Challenge from the ACME server. + type: string + identifier: + description: Identifier is the DNS name to be validated as part of this authorization + type: string + initialState: + description: InitialState is the initial state of the ACME authorization when first fetched from the ACME server. If an Authorization is already 'valid', the Order controller will not create a Challenge resource for the authorization. This will occur when working with an ACME server that enables 'authz reuse' (such as Let's Encrypt's production endpoint). If not set and 'identifier' is set, the state is assumed to be pending and a Challenge will be created. + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + url: + description: URL is the URL of the Authorization that must be completed + type: string + wildcard: + description: Wildcard will be true if this authorization is for a wildcard DNS name. If this is true, the identifier will be the *non-wildcard* version of the DNS name. For example, if '*.example.com' is the DNS name being validated, this field will be 'true' and the 'identifier' field will be 'example.com'. + type: boolean + certificate: + description: Certificate is a copy of the PEM encoded certificate for this Order. This field will be populated after the order has been successfully finalized with the ACME server, and the order has transitioned to the 'valid' state. + type: string + format: byte + failureTime: + description: FailureTime stores the time that this order failed. This is used to influence garbage collection and back-off. + type: string + format: date-time + finalizeURL: + description: FinalizeURL of the Order. This is used to obtain certificates for this order once it has been completed. + type: string + reason: + description: Reason optionally provides more information about a why the order is in the current state. + type: string + state: + description: State contains the current state of this Order resource. States 'success' and 'expired' are 'final' + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + url: + description: URL of the Order. This will initially be empty when the resource is first created. The Order controller will populate this field when the Order is first processed. This field will be immutable after it is initially set. + type: string + served: true + storage: true +{{- end }} diff --git a/cert-manager/templates/deployment.yaml b/cert-manager/templates/deployment.yaml new file mode 100644 index 0000000..b7f549e --- /dev/null +++ b/cert-manager/templates/deployment.yaml @@ -0,0 +1,170 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "cert-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ template "cert-manager.name" . }} + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- with .Values.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ template "cert-manager.name" . }} + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and .Values.prometheus.enabled (not .Values.prometheus.servicemonitor.enabled) }} + {{- if not .Values.podAnnotations }} + annotations: + {{- end }} + prometheus.io/path: "/metrics" + prometheus.io/scrape: 'true' + prometheus.io/port: '9402' + {{- end }} + spec: + serviceAccountName: {{ template "cert-manager.serviceAccountName" . }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- $enabledDefined := gt (len (keys (pick .Values.securityContext "enabled"))) 0 }} + {{- $legacyEnabledExplicitlyOff := and $enabledDefined (not .Values.securityContext.enabled) }} + {{- if and .Values.securityContext (not $legacyEnabledExplicitlyOff) }} + securityContext: + {{- if .Values.securityContext.enabled }} + {{/* support legacy securityContext.enabled and its two parameters */}} + fsGroup: {{ default 1001 .Values.securityContext.fsGroup }} + runAsUser: {{ default 1001 .Values.securityContext.runAsUser }} + {{- else }} + {{/* this is the way forward: support an arbitrary yaml block */}} + {{- toYaml .Values.securityContext | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- if .Values.clusterResourceNamespace }} + - --cluster-resource-namespace={{ .Values.clusterResourceNamespace }} + {{- else }} + - --cluster-resource-namespace=$(POD_NAMESPACE) + {{- end }} + {{- with .Values.global.leaderElection }} + - --leader-election-namespace={{ .namespace }} + {{- if .leaseDuration }} + - --leader-election-lease-duration={{ .leaseDuration }} + {{- end }} + {{- if .renewDeadline }} + - --leader-election-renew-deadline={{ .renewDeadline }} + {{- end }} + {{- if .retryPeriod }} + - --leader-election-retry-period={{ .retryPeriod }} + {{- end }} + {{- end }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.ingressShim }} + {{- if .defaultIssuerName }} + - --default-issuer-name={{ .defaultIssuerName }} + {{- end }} + {{- if .defaultIssuerKind }} + - --default-issuer-kind={{ .defaultIssuerKind }} + {{- end }} + {{- if .defaultIssuerGroup }} + - --default-issuer-group={{ .defaultIssuerGroup }} + {{- end }} + {{- end }} + {{- if .Values.featureGates }} + - --feature-gates={{ .Values.featureGates }} + {{- end }} + ports: + - containerPort: 9402 + name: http-metrics + protocol: TCP + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.http_proxy }} + - name: HTTP_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.https_proxy }} + - name: HTTPS_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.no_proxy }} + - name: NO_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podDnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} + {{- with .Values.podDnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/cert-manager/templates/psp-clusterrole.yaml b/cert-manager/templates/psp-clusterrole.yaml new file mode 100644 index 0000000..1d40a02 --- /dev/null +++ b/cert-manager/templates/psp-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cert-manager.fullname" . }}-psp + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "cert-manager.fullname" . }} +{{- end }} diff --git a/cert-manager/templates/psp-clusterrolebinding.yaml b/cert-manager/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000..1da89c8 --- /dev/null +++ b/cert-manager/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-psp + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/cert-manager/templates/psp.yaml b/cert-manager/templates/psp.yaml new file mode 100644 index 0000000..9e99f5c --- /dev/null +++ b/cert-manager/templates/psp.yaml @@ -0,0 +1,49 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "cert-manager.fullname" . }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} diff --git a/cert-manager/templates/rbac.yaml b/cert-manager/templates/rbac.yaml new file mode 100644 index 0000000..f8ead0c --- /dev/null +++ b/cert-manager/templates/rbac.yaml @@ -0,0 +1,545 @@ +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "cert-manager.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + resourceNames: ["cert-manager-controller"] + verbs: ["get", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] + +--- + +# grant cert-manager permission to manage the leaderelection configmap in the +# leader election namespace +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "cert-manager.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "cert-manager.fullname" . }}:leaderelection +subjects: + - apiGroup: "" + kind: ServiceAccount + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + +--- + +# Issuer controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-issuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["issuers", "issuers/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# ClusterIssuer controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers", "clusterissuers/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Certificates controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificates + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificates/status", "certificaterequests", "certificaterequests/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "clusterissuers", "issuers"] + verbs: ["get", "list", "watch"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["cert-manager.io"] + resources: ["certificates/finalizers", "certificaterequests/finalizers"] + verbs: ["update"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders"] + verbs: ["create", "delete", "get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Orders controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-orders + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders", "orders/status"] + verbs: ["update", "patch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders", "challenges"] + verbs: ["get", "list", "watch"] + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers", "issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges"] + verbs: ["create", "delete"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders/finalizers"] + verbs: ["update"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Challenges controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-challenges + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + # Use to update challenge resource status + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "challenges/status"] + verbs: ["update", "patch"] + # Used to watch challenge resources + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges"] + verbs: ["get", "list", "watch"] + # Used to watch challenges, issuer and clusterissuer resources + - apiGroups: ["cert-manager.io"] + resources: ["issuers", "clusterissuers"] + verbs: ["get", "list", "watch"] + # Need to be able to retrieve ACME account private key to complete challenges + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + # Used to create events + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + # HTTP01 rules + - apiGroups: [""] + resources: ["pods", "services"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "delete", "update"] + - apiGroups: [ "gateway.networking.k8s.io" ] + resources: [ "httproutes" ] + verbs: ["get", "list", "watch", "create", "delete", "update"] + # We require the ability to specify a custom hostname when we are creating + # new ingress resources. + # See: https://github.com/openshift/origin/blob/21f191775636f9acadb44fa42beeb4f75b255532/pkg/route/apiserver/admission/ingress_admission.go#L84-L148 + - apiGroups: ["route.openshift.io"] + resources: ["routes/custom-host"] + verbs: ["create"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges/finalizers"] + verbs: ["update"] + # DNS01 rules (duplicated above) + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + +--- + +# ingress-shim controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests"] + verbs: ["create", "update", "delete"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers", "clusterissuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses/finalizers"] + verbs: ["update"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gateways", "httproutes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gateways/finalizers", "httproutes/finalizers"] + verbs: ["update"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-issuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-issuers +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificates + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-certificates +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-orders + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-orders +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-challenges + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-challenges +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-view + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- if .Values.global.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["get", "list", "watch"] + + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-edit + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- if .Values.global.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates/status"] + verbs: ["update"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + +--- + +# Permission to approve CertificateRequests referencing cert-manager.io Issuers and ClusterIssuers +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["signers"] + verbs: ["approve"] + resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount + +--- + +# Permission to: +# - Update and sign CertificatSigningeRequests referencing cert-manager.io Issuers and ClusterIssuers +# - Perform SubjectAccessReviews to test whether users are able to reference Namespaced Issuers +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/status"] + verbs: ["update", "patch"] + - apiGroups: ["certificates.k8s.io"] + resources: ["signers"] + resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"] + verbs: ["sign"] + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + kind: ServiceAccount +{{- end }} diff --git a/cert-manager/templates/service.yaml b/cert-manager/templates/service.yaml new file mode 100644 index 0000000..8ad24ca --- /dev/null +++ b/cert-manager/templates/service.yaml @@ -0,0 +1,31 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "cert-manager.fullname" . }} + namespace: {{ .Release.Namespace | quote }} +{{- with .Values.serviceAnnotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + ports: + - protocol: TCP + port: 9402 + name: tcp-prometheus-servicemonitor + targetPort: {{ .Values.prometheus.servicemonitor.targetPort }} + selector: + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" +{{- end }} diff --git a/cert-manager/templates/serviceaccount.yaml b/cert-manager/templates/serviceaccount.yaml new file mode 100644 index 0000000..6e53f78 --- /dev/null +++ b/cert-manager/templates/serviceaccount.yaml @@ -0,0 +1,25 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/cert-manager/templates/servicemonitor.yaml b/cert-manager/templates/servicemonitor.yaml new file mode 100644 index 0000000..8ea1f63 --- /dev/null +++ b/cert-manager/templates/servicemonitor.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.servicemonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "cert-manager.fullname" . }} +{{- if .Values.prometheus.servicemonitor.namespace }} + namespace: {{ .Values.prometheus.servicemonitor.namespace }} +{{- else }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + prometheus: {{ .Values.prometheus.servicemonitor.prometheusInstance }} + {{- with .Values.prometheus.servicemonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ template "cert-manager.fullname" . }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" +{{- if .Values.prometheus.servicemonitor.namespace }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} + endpoints: + - targetPort: {{ .Values.prometheus.servicemonitor.targetPort }} + path: {{ .Values.prometheus.servicemonitor.path }} + interval: {{ .Values.prometheus.servicemonitor.interval }} + scrapeTimeout: {{ .Values.prometheus.servicemonitor.scrapeTimeout }} + honorLabels: {{ .Values.prometheus.servicemonitor.honorLabels }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-job.yaml b/cert-manager/templates/startupapicheck-job.yaml new file mode 100644 index 0000000..66db004 --- /dev/null +++ b/cert-manager/templates/startupapicheck-job.yaml @@ -0,0 +1,77 @@ +{{- if .Values.startupapicheck.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "startupapicheck.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.jobAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.startupapicheck.backoffLimit }} + template: + metadata: + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 8 }} + {{- with .Values.startupapicheck.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ template "startupapicheck.serviceAccountName" . }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.startupapicheck.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.startupapicheck.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.startupapicheck.image.pullPolicy }} + args: + - check + - api + - --wait={{ .Values.startupapicheck.timeout }} + {{- with .Values.startupapicheck.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.startupapicheck.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupapicheck.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupapicheck.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-psp-clusterrole.yaml b/cert-manager/templates/startupapicheck-psp-clusterrole.yaml new file mode 100644 index 0000000..dacd4be --- /dev/null +++ b/cert-manager/templates/startupapicheck-psp-clusterrole.yaml @@ -0,0 +1,24 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "startupapicheck.fullname" . }}-psp + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "startupapicheck.fullname" . }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml b/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml new file mode 100644 index 0000000..d19fa84 --- /dev/null +++ b/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml @@ -0,0 +1,26 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "startupapicheck.fullname" . }}-psp + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "startupapicheck.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-psp.yaml b/cert-manager/templates/startupapicheck-psp.yaml new file mode 100644 index 0000000..f09d60d --- /dev/null +++ b/cert-manager/templates/startupapicheck-psp.yaml @@ -0,0 +1,51 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "startupapicheck.fullname" . }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} + {{- with .Values.startupapicheck.rbac.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'projected' + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-rbac.yaml b/cert-manager/templates/startupapicheck-rbac.yaml new file mode 100644 index 0000000..a6be7b9 --- /dev/null +++ b/cert-manager/templates/startupapicheck-rbac.yaml @@ -0,0 +1,48 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.rbac.create }} +# create certificate role +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "startupapicheck.fullname" . }}:create-cert + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "startupapicheck.fullname" . }}:create-cert + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "startupapicheck.fullname" . }}:create-cert +subjects: + - kind: ServiceAccount + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/startupapicheck-serviceaccount.yaml b/cert-manager/templates/startupapicheck-serviceaccount.yaml new file mode 100644 index 0000000..46262d5 --- /dev/null +++ b/cert-manager/templates/startupapicheck-serviceaccount.yaml @@ -0,0 +1,27 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.startupapicheck.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.startupapicheck.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + {{- with .Values.startupapicheck.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/webhook-config.yaml b/cert-manager/templates/webhook-config.yaml new file mode 100644 index 0000000..29558e9 --- /dev/null +++ b/cert-manager/templates/webhook-config.yaml @@ -0,0 +1,24 @@ +{{- if .Values.webhook.config -}} + {{- if not .Values.webhook.config.apiVersion -}} + {{- fail "webhook.config.apiVersion must be set" -}} + {{- end -}} + + {{- if not .Values.webhook.config.kind -}} + {{- fail "webhook.config.kind must be set" -}} + {{- end -}} +{{- end -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "webhook.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" +data: + {{- if .Values.webhook.config }} + config.yaml: | + {{ .Values.webhook.config | toYaml | nindent 4 }} + {{- end }} diff --git a/cert-manager/templates/webhook-deployment.yaml b/cert-manager/templates/webhook-deployment.yaml new file mode 100644 index 0000000..0de1df2 --- /dev/null +++ b/cert-manager/templates/webhook-deployment.yaml @@ -0,0 +1,153 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "webhook.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.webhook.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- with .Values.webhook.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 8 }} + {{- with .Values.webhook.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "webhook.serviceAccountName" . }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.webhook.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.webhook.hostNetwork }} + hostNetwork: true + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.webhook.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.webhook.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- if .Values.webhook.config }} + - --config=/var/cert-manager/config/config.yaml + {{- end }} + {{- $config := default .Values.webhook.config "" }} + {{ if not $config.securePort -}} + - --secure-port={{ .Values.webhook.securePort }} + {{- end }} + {{- $tlsConfig := default $config.tlsConfig "" }} + {{ if or (not $config.tlsConfig) (and (not $tlsConfig.dynamic) (not $tlsConfig.filesystem) ) -}} + - --dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE) + - --dynamic-serving-ca-secret-name={{ template "webhook.fullname" . }}-ca + - --dynamic-serving-dns-names={{ template "webhook.fullname" . }},{{ template "webhook.fullname" . }}.{{ .Release.Namespace }},{{ template "webhook.fullname" . }}.{{ .Release.Namespace }}.svc{{ if .Values.webhook.url.host }},{{ .Values.webhook.url.host }}{{ end }} + {{- end }} + {{- with .Values.webhook.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - name: https + protocol: TCP + {{- if $config.securePort }} + containerPort: {{ $config.securePort }} + {{- else if .Values.webhook.securePort }} + containerPort: {{ .Values.webhook.securePort }} + {{- else }} + containerPort: 6443 + {{- end }} + livenessProbe: + httpGet: + path: /livez + {{- if $config.healthzPort }} + port: {{ $config.healthzPort }} + {{- else }} + port: 6080 + {{- end }} + scheme: HTTP + initialDelaySeconds: {{ .Values.webhook.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.webhook.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.webhook.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.webhook.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.webhook.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + {{- if $config.healthzPort }} + port: {{ $config.healthzPort }} + {{- else }} + port: 6080 + {{- end }} + scheme: HTTP + initialDelaySeconds: {{ .Values.webhook.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.webhook.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.webhook.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.webhook.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.webhook.readinessProbe.failureThreshold }} + {{- with .Values.webhook.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.webhook.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.webhook.config }} + volumeMounts: + - name: config + mountPath: /var/cert-manager/config + {{- end }} + {{- with .Values.webhook.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.webhook.config }} + volumes: + - name: config + configMap: + name: {{ include "webhook.fullname" . }} + {{- end }} diff --git a/cert-manager/templates/webhook-mutating-webhook.yaml b/cert-manager/templates/webhook-mutating-webhook.yaml new file mode 100644 index 0000000..fb8b795 --- /dev/null +++ b/cert-manager/templates/webhook-mutating-webhook.yaml @@ -0,0 +1,46 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ include "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from-secret: "{{ .Release.Namespace }}/{{ template "webhook.fullname" . }}-ca" + {{- with .Values.webhook.mutatingWebhookConfigurationAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: + - name: webhook.cert-manager.io + rules: + - apiGroups: + - "cert-manager.io" + - "acme.cert-manager.io" + apiVersions: + - "v1" + operations: + - CREATE + - UPDATE + resources: + - "*/*" + admissionReviewVersions: ["v1"] + # This webhook only accepts v1 cert-manager resources. + # Equivalent matchPolicy ensures that non-v1 resource requests are sent to + # this webhook (after the resources have been converted to v1). + matchPolicy: Equivalent + timeoutSeconds: {{ .Values.webhook.timeoutSeconds }} + failurePolicy: Fail + # Only include 'sideEffects' field in Kubernetes 1.12+ + sideEffects: None + clientConfig: + {{- if .Values.webhook.url.host }} + url: https://{{ .Values.webhook.url.host }}/mutate + {{- else }} + service: + name: {{ template "webhook.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + path: /mutate + {{- end }} diff --git a/cert-manager/templates/webhook-psp-clusterrole.yaml b/cert-manager/templates/webhook-psp-clusterrole.yaml new file mode 100644 index 0000000..2a8808e --- /dev/null +++ b/cert-manager/templates/webhook-psp-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "webhook.fullname" . }}-psp + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "webhook.fullname" . }} +{{- end }} diff --git a/cert-manager/templates/webhook-psp-clusterrolebinding.yaml b/cert-manager/templates/webhook-psp-clusterrolebinding.yaml new file mode 100644 index 0000000..e8e1bb2 --- /dev/null +++ b/cert-manager/templates/webhook-psp-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "webhook.fullname" . }}-psp + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "webhook.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/cert-manager/templates/webhook-psp.yaml b/cert-manager/templates/webhook-psp.yaml new file mode 100644 index 0000000..4d5d959 --- /dev/null +++ b/cert-manager/templates/webhook-psp.yaml @@ -0,0 +1,54 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: {{ .Values.webhook.hostNetwork }} + {{- if .Values.webhook.hostNetwork }} + hostPorts: + - max: {{ .Values.webhook.securePort }} + min: {{ .Values.webhook.securePort }} + {{- end }} + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} diff --git a/cert-manager/templates/webhook-rbac.yaml b/cert-manager/templates/webhook-rbac.yaml new file mode 100644 index 0000000..1070333 --- /dev/null +++ b/cert-manager/templates/webhook-rbac.yaml @@ -0,0 +1,83 @@ +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "webhook.fullname" . }}:dynamic-serving + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: [""] + resources: ["secrets"] + resourceNames: + - '{{ template "webhook.fullname" . }}-ca' + verbs: ["get", "list", "watch", "update"] +# It's not possible to grant CREATE permission on a single resourceName. +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "webhook.fullname" . }}:dynamic-serving + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "webhook.fullname" . }}:dynamic-serving +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "webhook.fullname" . }}:subjectaccessreviews + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "webhook.fullname" . }}:subjectaccessreviews + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "webhook.fullname" . }}:subjectaccessreviews +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/cert-manager/templates/webhook-service.yaml b/cert-manager/templates/webhook-service.yaml new file mode 100644 index 0000000..ed0278a --- /dev/null +++ b/cert-manager/templates/webhook-service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "webhook.fullname" . }} + namespace: {{ .Release.Namespace | quote }} +{{- with .Values.webhook.serviceAnnotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.webhook.serviceType }} + {{- with .Values.webhook.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + ports: + - name: https + port: 443 + protocol: TCP + targetPort: "https" + selector: + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" diff --git a/cert-manager/templates/webhook-serviceaccount.yaml b/cert-manager/templates/webhook-serviceaccount.yaml new file mode 100644 index 0000000..2792a43 --- /dev/null +++ b/cert-manager/templates/webhook-serviceaccount.yaml @@ -0,0 +1,25 @@ +{{- if .Values.webhook.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.webhook.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + {{- with .Values.webhook.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/cert-manager/templates/webhook-validating-webhook.yaml b/cert-manager/templates/webhook-validating-webhook.yaml new file mode 100644 index 0000000..2ca6403 --- /dev/null +++ b/cert-manager/templates/webhook-validating-webhook.yaml @@ -0,0 +1,55 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from-secret: "{{ .Release.Namespace }}/{{ template "webhook.fullname" . }}-ca" + {{- with .Values.webhook.validatingWebhookConfigurationAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: + - name: webhook.cert-manager.io + namespaceSelector: + matchExpressions: + - key: "cert-manager.io/disable-validation" + operator: "NotIn" + values: + - "true" + - key: "name" + operator: "NotIn" + values: + - {{ .Release.Namespace }} + rules: + - apiGroups: + - "cert-manager.io" + - "acme.cert-manager.io" + apiVersions: + - "v1" + operations: + - CREATE + - UPDATE + resources: + - "*/*" + admissionReviewVersions: ["v1"] + # This webhook only accepts v1 cert-manager resources. + # Equivalent matchPolicy ensures that non-v1 resource requests are sent to + # this webhook (after the resources have been converted to v1). + matchPolicy: Equivalent + timeoutSeconds: {{ .Values.webhook.timeoutSeconds }} + failurePolicy: Fail + sideEffects: None + clientConfig: + {{- if .Values.webhook.url.host }} + url: https://{{ .Values.webhook.url.host }}/validate + {{- else }} + service: + name: {{ template "webhook.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + path: /validate + {{- end }} diff --git a/cert-manager/values.yaml b/cert-manager/values.yaml new file mode 100644 index 0000000..3a21b15 --- /dev/null +++ b/cert-manager/values.yaml @@ -0,0 +1,543 @@ +# Default values for cert-manager. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +global: + ## Reference to one or more secrets to be used when pulling images + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + imagePullSecrets: [] + # - name: "image-pull-secret" + + # Optional priority class to be used for the cert-manager pods + priorityClassName: "" + rbac: + create: true + # Aggregate ClusterRoles to Kubernetes default user-facing roles. Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles + aggregateClusterRoles: true + + podSecurityPolicy: + enabled: false + useAppArmor: true + + # Set the verbosity of cert-manager. Range of 0 - 6 with 6 being the most verbose. + logLevel: 2 + + leaderElection: + # Override the namespace used to store the ConfigMap for leader election + namespace: "kube-system" + + # The duration that non-leader candidates will wait after observing a + # leadership renewal until attempting to acquire leadership of a led but + # unrenewed leader slot. This is effectively the maximum duration that a + # leader can be stopped before it is replaced by another candidate. + # leaseDuration: 60s + + # The interval between attempts by the acting master to renew a leadership + # slot before it stops leading. This must be less than or equal to the + # lease duration. + # renewDeadline: 40s + + # The duration the clients should wait between attempting acquisition and + # renewal of a leadership. + # retryPeriod: 15s + +installCRDs: false + +replicaCount: 1 + +strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + +# Comma separated list of feature gates that should be enabled on the +# controller pod. +featureGates: "" + +image: + repository: quay.io/jetstack/cert-manager-controller + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-controller + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + pullPolicy: IfNotPresent + +# Override the namespace used to store DNS provider credentials etc. for ClusterIssuer +# resources. By default, the same namespace as cert-manager is deployed within is +# used. This namespace will not be automatically created by the Helm chart. +clusterResourceNamespace: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Automount API credentials for a Service Account. + # Optional additional labels to add to the controller's ServiceAccount + # labels: {} + automountServiceAccountToken: true + +# Additional command line flags to pass to cert-manager controller binary. +# To see all available flags run docker run quay.io/jetstack/cert-manager-controller: --help +extraArgs: [] + # When this flag is enabled, secrets will be automatically removed when the certificate resource is deleted + # - --enable-certificate-owner-ref=true + # Use this flag to enabled or disable arbitrary controllers, for example, disable the CertificiateRequests approver + # - --controllers=*,-certificaterequests-approver + +extraEnv: [] +# - name: SOME_VAR +# value: 'some value' + +resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + +# Pod Security Context +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + runAsNonRoot: true +# legacy securityContext parameter format: if enabled is set to true, only fsGroup and runAsUser are supported +# securityContext: +# enabled: false +# fsGroup: 1001 +# runAsUser: 1001 +# to support additional securityContext parameters, omit the `enabled` parameter and simply specify the parameters +# you want to set, e.g. +# securityContext: +# fsGroup: 1000 +# runAsUser: 1000 +# runAsNonRoot: true + +# Container Security Context to be set on the controller component container +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +containerSecurityContext: + allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + +volumes: [] + +volumeMounts: [] + +# Optional additional annotations to add to the controller Deployment +# deploymentAnnotations: {} + +# Optional additional annotations to add to the controller Pods +# podAnnotations: {} + +podLabels: {} + +# Optional annotations to add to the controller Service +# serviceAnnotations: {} + +# Optional additional labels to add to the controller Service +# serviceLabels: {} + +# Optional DNS settings, useful if you have a public and private DNS zone for +# the same domain on Route 53. What follows is an example of ensuring +# cert-manager can access an ingress or DNS TXT records at all times. +# NOTE: This requires Kubernetes 1.10 or `CustomPodDNS` feature gate enabled for +# the cluster to work. +# podDnsPolicy: "None" +# podDnsConfig: +# nameservers: +# - "1.1.1.1" +# - "8.8.8.8" + +nodeSelector: + kubernetes.io/os: linux + +ingressShim: {} + # defaultIssuerName: "" + # defaultIssuerKind: "" + # defaultIssuerGroup: "" + +prometheus: + enabled: true + servicemonitor: + enabled: false + prometheusInstance: default + targetPort: 9402 + path: /metrics + interval: 60s + scrapeTimeout: 30s + labels: {} + honorLabels: false + +# Use these variables to configure the HTTP_PROXY environment variables +# http_proxy: "http://proxy:8080" +# https_proxy: "https://proxy:8080" +# no_proxy: 127.0.0.1,localhost + +# expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#affinity-v1-core +# for example: +# affinity: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: foo.bar.com/role +# operator: In +# values: +# - master +affinity: {} + +# expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#toleration-v1-core +# for example: +# tolerations: +# - key: foo.bar.com/role +# operator: Equal +# value: master +# effect: NoSchedule +tolerations: [] + +webhook: + replicaCount: 1 + timeoutSeconds: 10 + + # Used to configure options for the webhook pod. + # This allows setting options that'd usually be provided via flags. + # An APIVersion and Kind must be specified in your values.yaml file. + # Flags will override options that are set here. + config: + # apiVersion: webhook.config.cert-manager.io/v1alpha1 + # kind: WebhookConfiguration + + # The port that the webhook should listen on for requests. + # In GKE private clusters, by default kubernetes apiservers are allowed to + # talk to the cluster nodes only on 443 and 10250. so configuring + # securePort: 10250, will work out of the box without needing to add firewall + # rules or requiring NET_BIND_SERVICE capabilities to bind port numbers <1000. + # This should be uncommented and set as a default by the chart once we graduate + # the apiVersion of WebhookConfiguration past v1alpha1. + # securePort: 10250 + + strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + + # Pod Security Context to be set on the webhook component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + + # Container Security Context to be set on the webhook component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + # Optional additional annotations to add to the webhook Deployment + # deploymentAnnotations: {} + + # Optional additional annotations to add to the webhook Pods + # podAnnotations: {} + + # Optional additional annotations to add to the webhook Service + # serviceAnnotations: {} + + # Optional additional annotations to add to the webhook MutatingWebhookConfiguration + # mutatingWebhookConfigurationAnnotations: {} + + # Optional additional annotations to add to the webhook ValidatingWebhookConfiguration + # validatingWebhookConfigurationAnnotations: {} + + # Additional command line flags to pass to cert-manager webhook binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-webhook: --help + extraArgs: [] + # Path to a file containing a WebhookConfiguration object used to configure the webhook + # - --config= + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + ## Liveness and readiness probe values + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 1 + + nodeSelector: + kubernetes.io/os: linux + + affinity: {} + + tolerations: [] + + # Optional additional labels to add to the Webhook Pods + podLabels: {} + + # Optional additional labels to add to the Webhook Service + serviceLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-webhook + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-webhook + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Optional additional labels to add to the webhook's ServiceAccount + # labels: {} + # Automount API credentials for a Service Account. + automountServiceAccountToken: true + + # The port that the webhook should listen on for requests. + # In GKE private clusters, by default kubernetes apiservers are allowed to + # talk to the cluster nodes only on 443 and 10250. so configuring + # securePort: 10250, will work out of the box without needing to add firewall + # rules or requiring NET_BIND_SERVICE capabilities to bind port numbers <1000 + securePort: 10250 + + # Specifies if the webhook should be started in hostNetwork mode. + # + # Required for use in some managed kubernetes clusters (such as AWS EKS) with custom + # CNI (such as calico), because control-plane managed by AWS cannot communicate + # with pods' IP CIDR and admission webhooks are not working + # + # Since the default port for the webhook conflicts with kubelet on the host + # network, `webhook.securePort` should be changed to an available port if + # running in hostNetwork mode. + hostNetwork: false + + # Specifies how the service should be handled. Useful if you want to expose the + # webhook to outside of the cluster. In some cases, the control plane cannot + # reach internal services. + serviceType: ClusterIP + # loadBalancerIP: + + # Overrides the mutating webhook and validating webhook so they reach the webhook + # service using the `url` field instead of a service. + url: {} + # host: + +cainjector: + enabled: true + replicaCount: 1 + + strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + + # Pod Security Context to be set on the cainjector component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + + # Container Security Context to be set on the cainjector component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + + # Optional additional annotations to add to the cainjector Deployment + # deploymentAnnotations: {} + + # Optional additional annotations to add to the cainjector Pods + # podAnnotations: {} + + # Additional command line flags to pass to cert-manager cainjector binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-cainjector: --help + extraArgs: [] + # Enable profiling for cainjector + # - --enable-profiling=true + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + nodeSelector: + kubernetes.io/os: linux + + affinity: {} + + tolerations: [] + + # Optional additional labels to add to the CA Injector Pods + podLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-cainjector + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-cainjector + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Automount API credentials for a Service Account. + # Optional additional labels to add to the cainjector's ServiceAccount + # labels: {} + automountServiceAccountToken: true + +# This startupapicheck is a Helm post-install hook that waits for the webhook +# endpoints to become available. +# The check is implemented using a Kubernetes Job- if you are injecting mesh +# sidecar proxies into cert-manager pods, you probably want to ensure that they +# are not injected into this Job's pod. Otherwise the installation may time out +# due to the Job never being completed because the sidecar proxy does not exit. +# See https://github.com/cert-manager/cert-manager/pull/4414 for context. +startupapicheck: + enabled: true + + # Pod Security Context to be set on the startupapicheck component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + + # Container Security Context to be set on the controller component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + # Timeout for 'kubectl check api' command + timeout: 1m + + # Job backoffLimit + backoffLimit: 4 + + # Optional additional annotations to add to the startupapicheck Job + jobAnnotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "1" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + # Optional additional annotations to add to the startupapicheck Pods + # podAnnotations: {} + + # Additional command line flags to pass to startupapicheck binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-ctl: --help + extraArgs: [] + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + nodeSelector: {} + + affinity: {} + + tolerations: [] + + # Optional additional labels to add to the startupapicheck Pods + podLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-ctl + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-ctl + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + rbac: + # annotations for the startup API Check job RBAC and PSP resources + annotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + serviceAccount: + # Specifies whether a service account should be created + create: true + + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + + # Optional additional annotations to add to the Job's ServiceAccount + annotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + # Automount API credentials for a Service Account. + automountServiceAccountToken: true + + # Optional additional labels to add to the startupapicheck's ServiceAccount + # labels: {} From e42a2cf2f36ccec72f48b63bcc556b1af45ae66a Mon Sep 17 00:00:00 2001 From: Marat Date: Sat, 18 Jun 2022 19:52:23 +0400 Subject: [PATCH 09/17] asd --- cert-manager/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cert-manager/values.yaml b/cert-manager/values.yaml index 3a21b15..15c1cf0 100644 --- a/cert-manager/values.yaml +++ b/cert-manager/values.yaml @@ -41,7 +41,7 @@ global: # renewal of a leadership. # retryPeriod: 15s -installCRDs: false +installCRDs: true replicaCount: 1 From 17595bfe41e7b4285af09f4b1fbea40cedd4f938 Mon Sep 17 00:00:00 2001 From: Marat Date: Sat, 18 Jun 2022 19:58:04 +0400 Subject: [PATCH 10/17] qwe --- apps/templates/cert-manager.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/templates/cert-manager.yaml b/apps/templates/cert-manager.yaml index 7d59ffc..be2e63e 100644 --- a/apps/templates/cert-manager.yaml +++ b/apps/templates/cert-manager.yaml @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: cert-manager - namespace: cert-manager + namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: From 0de82dc961720b9f89d8ebc1bca1f3b6f9afae02 Mon Sep 17 00:00:00 2001 From: Marat Date: Sun, 19 Jun 2022 14:38:04 +0400 Subject: [PATCH 11/17] asd --- my-bloody-jenkins/.helmignore | 21 ++ my-bloody-jenkins/Chart.yaml | 17 ++ my-bloody-jenkins/README.md | 192 +++++++++++++ my-bloody-jenkins/logo/jenkins-logo.png | Bin 0 -> 29020 bytes my-bloody-jenkins/templates/NOTES.txt | 39 +++ my-bloody-jenkins/templates/_helpers.tpl | 67 +++++ my-bloody-jenkins/templates/config.yaml | 32 +++ my-bloody-jenkins/templates/deployment.yaml | 224 +++++++++++++++ .../templates/ingress-tls-secret.yaml | 17 ++ my-bloody-jenkins/templates/ingress.yaml | 64 +++++ my-bloody-jenkins/templates/pvc.yaml | 59 ++++ my-bloody-jenkins/templates/rbac.yaml | 58 ++++ my-bloody-jenkins/templates/secret.yaml | 16 ++ my-bloody-jenkins/templates/service.yaml | 40 +++ my-bloody-jenkins/values.yaml | 254 ++++++++++++++++++ 15 files changed, 1100 insertions(+) create mode 100644 my-bloody-jenkins/.helmignore create mode 100644 my-bloody-jenkins/Chart.yaml create mode 100644 my-bloody-jenkins/README.md create mode 100644 my-bloody-jenkins/logo/jenkins-logo.png create mode 100644 my-bloody-jenkins/templates/NOTES.txt create mode 100644 my-bloody-jenkins/templates/_helpers.tpl create mode 100644 my-bloody-jenkins/templates/config.yaml create mode 100644 my-bloody-jenkins/templates/deployment.yaml create mode 100644 my-bloody-jenkins/templates/ingress-tls-secret.yaml create mode 100644 my-bloody-jenkins/templates/ingress.yaml create mode 100644 my-bloody-jenkins/templates/pvc.yaml create mode 100644 my-bloody-jenkins/templates/rbac.yaml create mode 100644 my-bloody-jenkins/templates/secret.yaml create mode 100644 my-bloody-jenkins/templates/service.yaml create mode 100644 my-bloody-jenkins/values.yaml diff --git a/my-bloody-jenkins/.helmignore b/my-bloody-jenkins/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/my-bloody-jenkins/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/my-bloody-jenkins/Chart.yaml b/my-bloody-jenkins/Chart.yaml new file mode 100644 index 0000000..ff89951 --- /dev/null +++ b/my-bloody-jenkins/Chart.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +name: my-bloody-jenkins +version: 0.1.186 +appVersion: "2.332.3-277" +icon: https://raw.githubusercontent.com/odavid/k8s-helm-charts/master/charts/my-bloody-jenkins/logo/jenkins-logo.png +description: > + A Helm chart for my-bloody-jenkins - a self configured jenkins docker image, based on Jenkins LTS. + Inspired by https://github.com/kubernetes/charts/tree/master/stable/jenkins, but better suites https://github.com/odavid/my-bloody-jenkins +sources: + - https://github.com/odavid/my-bloody-jenkins + - https://github.com/odavid/k8s-helm-charts/tree/master/charts/my-bloody-jenkins + - https://github.com/odavid/jenkins-jnlp-slave +maintainers: + - name: odavid + email: ohad.david@gmail.com +home: https://github.com/odavid/my-bloody-jenkins diff --git a/my-bloody-jenkins/README.md b/my-bloody-jenkins/README.md new file mode 100644 index 0000000..9b54ffb --- /dev/null +++ b/my-bloody-jenkins/README.md @@ -0,0 +1,192 @@ +# My Bloody Jenkins + +## Prerequisites Details +* Kubernetes 1.8+ + +## Chart Details +The chart will do the following: +* Deploy [My Bloody Jenkins](https://github.com/odavid/my-bloody-jenkins) +* Manage Configuration in a dedicated ConfigMap +* Configures Jenkins to use a default [k8s jenkins cloud](https://plugins.jenkins.io/kubernetes) +* Optionally expose Jenkins with [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) +* Manages a [Persistent Volume Claim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) for Jenkins Storage +* Optionally mount extenral [secrets](https://kubernetes.io/docs/concepts/configuration/secret/) as volumes to be used within the configuration [See docs](https://github.com/odavid/my-bloody-jenkins/pull/102) +* Optionally mount external [configMaps](https://kubernetes-v1-4.github.io/docs/user-guide/configmap/) to be used as configuration data sources [See docs](https://github.com/odavid/my-bloody-jenkins/pull/102) +* Optionally configures [rbac](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) and a dedicated [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + + +## Installing the Chart +First add the following repo: + +```shell +helm repo add odavid https://odavid.github.io/k8s-helm-charts +``` + +To install the chart with the release name `jenkins`: +```shell +helm install --name jenkins odavid/my-bloody-jenkins +``` + +To install the chart with a custom configuration values.yml +```shell +helm install --name jenkins odavid/my-bloody-jenkins -f +``` + +## Upgrading the Release +To install the chart with a custom configuration values.yml +```shell +helm upgrade jenkins odavid/my-bloody-jenkins -f +``` + +## Deleting the Chart +```shell +helm delete jenkins +``` + +## Docker Image +By default the chart uses the [latest release of `odavid/my-bloody-jenkins`](https://hub.docker.com/r/odavid/my-bloody-jenkins/tags/) image. +The Helm Chart provides a way to use different repo or tags: +* `image.repository` - by default `odavid/my-bloody-jenkins` +* `image.tag` +* `image.pullPolicy` - by default `IfNotPresent` +* `image.imagePullSecret` - not set by default + + +## CPU and Memory Resources +The Helm chart comes with support for configured resource requests and limits. +By default these values are commented out. +It is __highly__ recommended to change this behavior on a production deployment. Also the Helm Chart provides a way to control Jenkins Java Memory Opts. When using Jenkins in production, you will need to set the values that suites your needs. + +## Persistence +By default the helm chart allocates a 20gb volume for jenkins storage. +The chart provides the ability to control: +* `persistence.jenkinsHome.enabled` - if set to false, jenkins home will be using empty{} volume instead of persistentVolumeClaim. Default is `true` +* `persistence.jenkinsHome.size` - the managed volume size +* `persistence.jenkinsHome.storageClass` - If set to `"-"`, then storageClass: `""`, which disables dynamic provisioning. If undefined (the default) or set to null, no storageClass spec is set, choosing the default provisioner. (gp2 on AWS, standard on GKE, AWS & OpenStack) +* `persistence.jenkinsHome.existingClaim` - if provided, jenkins storage will be stored on an manually managed persistentVolumeClaim +* `persistence.jenkinsHome.annotations` - annotations that will be added to the managed persistentVolumeClaim + +## Secrets +My Bloody Jenkins natively supports [environment variable substitution](https://github.com/odavid/my-bloody-jenkins#environment-variable-substitution-and-remove-master-env-vars) within its configuration files. +The Helm Chart provides a simple way to map [k8s secrets] in dedicated folders that will be later on used as environment variables datasource. + +In order to use this feature, you will need to create external secrets and then use: `envSecrets` property to add these secrets to the search order. +For example: +```shell +echo -n 'admin' > ./username +echo -n 'password' > ./password +kubectl create secret generic my-jenkins-secret --from-file=./username --from-file=./password +``` + +Then add this secret to values.yml: +```yaml +envSecrets: + - my-jenkins-secret +``` +Now, you can refer these secrets as environmnet variables: +* `MY_JENKINS_SECRET_USERNAME` +* `MY_JENKINS_SECRET_PASSWORD` + +See [Support multiple data sources and secrets from files](https://github.com/odavid/my-bloody-jenkins/pull/102) for more details + +The chart also support creating a dedicated k8s secret, which all its keys will become `JENKINS_SECRET_`. In order to use it, you will need to provided a key/value dict under the `secrets` value + +## Managed Configuration and additional ConfigMaps +My Bloody Jenkins natively supports watching multiple config data sources and merge them into one config top to bottom +The Helm Chart provides a way to define a `managedConfig` yaml within the chart values.yml as well as add additional external `configMaps` that will be merged/override the default configuration. + +See [Support multiple data sources and secrets from files](https://github.com/odavid/my-bloody-jenkins/pull/102) for more details +The `managedConfig` is mounted as `/var/jenkins_managed_config/jenkins-config.yml` and contains the `managedConfig` yaml contents + +Additional `configMaps` list are mounted as `/var/jenkins_config/` within the container and are merged with the `managedConfig` + +## Default K8S Jenkins Cloud for provisioning slaves within k8s +By default the Helm Chart Configures a [kubernetes cloud](https://plugins.jenkins.io/kubernetes) with a simple jnlp slave template. +For disabling this behavior, you need to set `defaultK8sCloud.enabled` to `false` +The following attributes can control the default template: +* `defaultK8sCloud.name` - the name of the k8s cloud - default (`k8s`) +* `defaultK8sCloud.labels` - list of agent labels that are used to provision the node - e.g. ```node(labels){}``` pipeline step - default (`["generic"]`) +* `defaultK8sCloud.jvmArgs` - JVM Args for the JNLP Slave - default (`"-Xmx1g"`) +* `defaultK8sCloud.remoteFs` - JNLP Remote FS - default (`"/home/jenkins"`) +* `defaultK8sCloud.image` - JNLP Slave Image - default (`"odavid/jenkins-jnlp-slave:latest"`) + +## Configuration + +The following table lists the configurable parameters of the chart and their default values. + +| Parameter | Description | Default | +|---------------------------|-----------------------------------|----------------------------------------------------------| +| `managedConfig` | `My Bloody Jenkins` Configuration yaml - See [Configuration Reference](https://github.com/odavid/my-bloody-jenkins#configuration-reference) | +| `defaultK8sCloud.enabled` | If `true` a default k8s jenkins cloud will be configured to enable automatic slave provisioning | `true` +| `defaultK8sCloud.name` | The name of the default k8s cloud | `k8s` +| `defaultK8sCloud.labels` | List of labels that mark the k8s provisioned slaves, use `node(label){}` within pipeline | `["generic"]` +| `defaultK8sCloud.jvmArgs` | Default JVM Args to pass to the jnlp slave of the k8s cloud | `-Xmx1g` +| `defaultK8sCloud.remoteFs` | The remoteFS of the JNLP Slave | `/home/jenkins` +| `defaultK8sCloud.image` | The docker image of the JNLP Slave | `odavid/jenkins-jnlp-slave:latest` +| `image.repository` | `My Bloody Jenkins` Docker Image | `odavid/my-bloody-jenkins` +| `image.tag` | `My Bloody Jenkins` Docker Image Tag | `2.121.1-62` +| `image.pullPolicy` | Image Pull Policy | `IfNotPresent` +| `image.imagePullSecrets` | Docker registry pull secret | +| `service.type` | Service Type | `LoadBalanacer` +| `service.externalTrafficPolicy` | externalTrafficPolicy | +| `service.annotations` | Service Annotations | `{}` +| `service.loadBalancerSourceRanges` | Array Of IP CIDR ranges to whitelist (Only if service type is `LoadBalancer`) | +| `service.loadBalancerIP` | Service Load Balancer IP Address (Only if service type is `LoadBalancer`) | +| `ingress.enabled` | If `true` Ingress will be created | `false` +| `ingress.httpProtocol` | Change to https if the ingress uses tls or you are using external tls termination using annotations | `http` +| `ingress.path` | Ingress Path (Only if ingress is enabled)| `/` +| `ingress.additionalRules` | Additional Ingress Rules| `[]` that will be appended to the actual ingress rule. +| `ingress.preAdditionalRules` | Additional Ingress Rules| `[]` that will be pre-appended to the actual ingress rule. Useful when using alb ingress class with [actions](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions) +| `ingress.annotations` | Ingress Annoations| `{}` +| `ingress.labels` | Ingress Labels| `{}` +| `ingress.hostname` | Ingress Hostname | +| `ingress.ingressClassName` | Ingress Class Name | +| `ingress.pathType` | Ingress Path Type | `Prefix` +| `ingress.tls.secretName` | Ingress TLS Secret Name - if provided, the ingress will terminate TLS using the certificate and private key in this secret. This setting is mutually exclusive with ingress.tls.certificate and ingress.tls.privateKey| +| `ingress.tls.certificate` | Ingress TLS Certificate - if provided, the ingress will use this certificate. Use in conjunction with ingress.tls.privateKey| +| `ingress.tls.privateKey` | Ingress TLS private key - if provided, the ingress will use this private key. Use in conjunction with ingress.tls.certificate | +| `rbac.create` | If `true` - a ServiceAccount, and a Role will be created| `true` +| `rbac.createServiceAccount` | If `createServiceAccount` = `false`, and `rbac.create` = `true`, the chart will only use the `rbac.serviceAaccountName` within RoleBindings | true +| `rbac.serviceAccountName` | Ignored if createServiceAccount = true | `default` +| `rbac.serviceAccount.annotations` | Specify ServiceAccount annotations | {} +| `rbac.clusterWideAccess` | If `true` - A ClusterRole will be created instead of Role - relevant only if `rbac.create` is `true`| `false` +| `resources.requests.cpu` | Initial CPU Request | +| `resources.requests.memory` | Initial Memory Request | +| `resources.limits.cpu` | CPU Limit | +| `resources.limits.memory` | Memory Limit | +| `readinessProbe.timeoutSeconds` | Readiness Probe Timeout in seconds | `5` +| `readinessProbe.initialDelaySeconds` | Readiness Probe Initial Delay in seconds | `5` +| `readinessProbe.periodSeconds` | Readiness Probe - check for readiess every `X` seconds | `5` +| `readinessProbe.failureThreshold` | Readiness Probe - Mark the pod as not ready for traffic after `X` consecutive failures | `3` +| `livenessProbe.timeoutSeconds` | Liveness Probe Timeout in seconds | `5` +| `livenessProbe.initialDelaySeconds` | Liveness Probe Initial Delay in seconds - a high value since it takes time to start| `600` +| `livenessProbe.periodSeconds` | Liveness Probe - check for liveness every `X` seconds | `5` +| `livenessProbe.failureThreshold` | Liveness Probe - Kill the pod after `X` consecutive failures | `3` +| `persistence.mountDockerSocket` | If `true` - `/var/run/docker.sock` will be mounted | `true` +| `persistence.jenkinsHome.enabled` | If `true` - Jenkins Storage will be persistent | `true` +| `persistence.jenkinsHome.existingClaim` | External Jenkins Storage PesistentVolumeClaim - if set, then no volume claim will be created by the Helm Chart| +| `persistence.jenkinsHome.annotations` | Jenkins Storage PesistentVolumeClaim annotations | `{}` +| `persistence.jenkinsHome.accessMode` | Jenkins Storage PesistentVolumeClaim accessMode | `ReadWriteOnce` +| `persistence.jenkinsHome.size` | Jenkins Storage PesistentVolumeClaim size | `20Gi` +| `persistence.jenkinsHome.storageClass` | External Jenkins Storage PesistentVolumeClaim | If set to `"-"`, then storageClass: `""`, which disables dynamic provisioning. If undefined (the default) or set to null, no storageClass spec is set, choosing the default provisioner. (gp2 on AWS, standard on GKE, AWS & OpenStack) +| `persistence.jenkinsWorkspace.enabled` | If `true` - Jenkins Workspace Storage will be persistent | `false` +| `persistence.jenkinsWorkspace.existingClaim` | External Jenkins Workspace Storage PesistentVolumeClaim - if set, then no volume claim will be created by the Helm Chart| +| `persistence.jenkinsWorkspace.annotations` | Jenkins Workspace Storage PesistentVolumeClaim annotations | `{}` +| `persistence.jenkinsWorkspace.accessMode` | Jenkins Workspace Storage PesistentVolumeClaim accessMode | `ReadWriteOnce` +| `persistence.jenkinsWorkspace.size` | Jenkins Workspace Storage PesistentVolumeClaim size | `8Gi` +| `persistence.jenkinsWorkspace.storageClass` | External Jenkins Workspace Storage PesistentVolumeClaim | If set to `"-"`, then storageClass: `""`, which disables dynamic provisioning. If undefined (the default) or set to null, no storageClass spec is set, choosing the default provisioner. (gp2 on AWS, standard on GKE, AWS & OpenStack) +| `podAnnotations` | Additional Pod Annotations | `{}` +| `persistence.volumes` | Additional volumes to be included within the Deployments | +| `persistence.mounts` | Additional mounts to be mounted to the container | +| `nodeSelector` | Node Selector | `{}` +| `tolerations` | Tolerations | `[]` +| `securityContxet` | Security Context for jenkins pod | `{}` +| `affinity` | Affinity | `{}` +| `env` | Additional Environment Variables to be passed to the container - format `key`: `value` | +| `secret` | A dict containing KEY/VALUE pairs. Each pair will become an environment variable `JENKINS_SECRET_`, if the `secrets` dict is not empty a k8s secret will be created| +| `envSecrets` | List of external secret names to be mounted as env secrets - see [Docs](https://github.com/odavid/my-bloody-jenkins/pull/102) | +| `configMaps` | List of external config maps to be used as configuration files - see [Docs](https://github.com/odavid/my-bloody-jenkins/pull/102) | +| `jenkinsAdminUser` | The name of the admin user - must be a valid user within the [Jenkins Security Realm](https://github.com/odavid/my-bloody-jenkins#security-section)| `admin` +| `javaMemoryOpts` | Jenkins Java Memory Opts | `-Xmx256m` +| `useHostNetwork` | If true, jenkins master will use hostNetwork | `false` +| `jenkinsURL` | Set the jenkinsURL configuration. If not set and ingress is enabled, then jenkins URL is {{ .Values.ingress.httpProtocol }}://{{ .Values.ingress.hostname }}{{ .Values.ingress.path }} | diff --git a/my-bloody-jenkins/logo/jenkins-logo.png b/my-bloody-jenkins/logo/jenkins-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0eb450cc12038c3e8fc1941d6f25005eb37d1c12 GIT binary patch literal 29020 zcmXt918`jL*N$y84H`6d(%4NJv%$u8vaxO3w%OQhY&O~0wvBIp|C#U3?A*o7z3-m) z;5pBEZuoC`2~;EkBnSuyR4GYOCGfco0s;~O0S^4`k^}?*pI{tCq*M^VhZllz82B@y zouq~%1O&3ye=o>Y)>$0zm-tR%>Q2hGrcSN~4ki$;uC7cLHb6%s13MEYTL-hu3w{C! z2vP_sQDGIgtg~!aFBOx;;hq-R@uE-)CsX|+Ksyq`l46~q7II2cXEUI#3J6+oX4G;z zZ(khLg`kfJBSk`zWcCljA{9tHKHqqZl?tJCO^_lNe!m_KO+RclGo2E6Xy@H@Zv^^A~?NDh1vMiWNpL3Us5 zH?2d17KiRH`0!}zFZTM$T8pX<#{lQUL`RF(+~0(z@y4`g4Usu$2~z?|4f?#l=so84 zD-MG7VKvA{ci!^iB?4asS<%)f3o#3c2)fAmEGnUZ=!yACL{aMcAtpywV#}4x7S8HR zrKozI8FVS+5L)){+dL>e$Z1HD&lK5=&0v1mC5FYnL9nk-d7fIidZmd{Z1|XBm{M5% zpON2fV(~n)8>*S%Yf0P)+#1V@mR5=Jj%1&7MhN{U4YQHnf@>dau*4d}{*AEtj1cD8-|)eqFrj3~oHlW^HNf7v& zCw@Q#WVe__K@ANJSs@SJVPa2|_m}&~DEf%Lx#DrRoonhVH~#o*a_Xp^3#~sz5-kCo zIn@ybK|c}mLqvjnsVU!j3i1j9D)I^-MBasd!(xJcSs4~mF$seLUpNU91`%dSPj{5? z(r3(*#5a6?-@*#ZxmQDsau9j-ssEeGn`uzz#Y0nD@kEyCPRc3MK~?&2v!yN_oh6Om3h9J2%bTV}u4E_87(xP?aOv@lthMXhTWt-TLa}OB1Pc zo~XxDn4SxmXn*X&W(I}Td(#p$G3{IG5cVcyH~V^H}c>T@ntZGKg7_s34KL{k`7={fnE&*CFI;#5vL6}g*(B^(KJ|G5rW{p9uz># zn=dxU!2ht;G4XD$SU)MRuLL$dGrYYt<4}#r$m#nA353L;?df6{;p3(&N!RPZBJ0^k zS12={PxL(g)D1FRAcMvms;;g2>xnb(htFm%_d!`W?IhWrBj!yTUvbyE693JeRwvu% zs&VEc#4dWUSL(0-`3zoPG7I!>OEdvT1mEQgGCn>$L+Wpuf%;2d{mBfyu#dA-P_+?g z3JYRxk}Ah*Z#s(4$~+OImW%tB2t>Nv}1Y&RB^!9Am^@p2Z z)97g^6tRddb?A-j5>BU}Q0m$pjh5?~RP#7|5VUyqgA4|r2NYxQq#-UMHTEDvE5rEO zRq1Kl!3xk2rn9p%z;(l0NVpeQ%wT<`)?&HAlgyU?6_fmH$L+HKg{IGbLJ@I-?VC-G<1}jh)<*}! zA5**e$^{{u6n96p*T_(!AQVx_EYMN6o?Bzac;v)Q5lr+1Z!b2Gs_TI$L5#08qO7Cb zZ>Hx{o=!lB0;kdCkz7$h*P_j(^;N*o4m(u^(c?U{>awFP4)yqG{x&WeU$Pz&Ccct6 zeK3i9h=OkbZp{&+H0=i(&wnvEj9ua%wsllk>iED@r%APiel;2}&CcP*^3{0q1mL!2 zvwcL1{SSFcuzVI+Q6b%HO^x%k@DGzBm=xh?f=4n$Gz3)`!)-5zkbv#@09;$*&w2lT z*^0w<*ix9at*`&_+ynezHiZWOo(;Fv&emIEPb%oZmKDs!s{zRXOekeiy=2@q@aq|9 zTXcmwW?4+tdx44pAB&Tk7??p*pU&eY45GB|e}=Uy#?^U3P={ehAyn{aZxyCo(B`^78q3s7ZZ3StThiuLfR} z|H;Efd?v$1sn@6yf|ODdoD>EH@ZVRW=PFoMlu3vARkmyR*a;`h;m)HOyIpz?neh5aii2eTp8Gk~GVWt}T&~iqs-o0ccy0=EAi~N3 z*U1O+EW8aX$m!A1e6>s6yW@4jSkSl{a{sdP>v(0*eP+a0&ZQFjBd&Bw<>P4caOxks@BZSH(X z*}93~Lc-GvT{OaH&Y79cZh8xuSpp1J2C7vl0qsJKNZ^ryOb@I5=Nss0Kk5@neJgz%KKs4aungv>zg((|0}wq(}gKY$}BiUhUM)d(J^c-gX2~ZL7VNTdF8oIllXuGkh|1pX9n(fm^Awm|+CG?hYxcLSX+cL{Bi0cGJ zcA0b#0miN(X+H&z`&a}7vX@gQ4)ziiq-z7abeUIMF7;QN&(Bu6_=cJ{>bk-vGdaaJ zYMxHy=41_IX!abj?~13s(;v%?4At@!RnR>O-k@Age`?S)4t9uRokz$SaM`04HrORxGd5c6$N3NN~zi13J}rfg`ggRhK^Oz+kQS<07` z?J`FqXCE3B@^Ze=?^Zr@YBo_KF*7;7wyS{*00|Ec(Ct~i8vSJj!q(gP)N)6v0ZOOd z_})}&?m^SSc|;zA8xqD;cnG86nC(9umwo2^wP@94W%|#t^fViab9pu9P&3hc_ z0*CamOA#N4`|T}YqIE8(HJzhPdLTn+X*CTJz1qh_M6wX&K6O+m(P978_^3D_$y9=L z(1Y>f7T)cw9Awyh?EK@i_0e)Dmf&BNBk>rw*969&u08gT_nXk`%o3MgC&QWL1X@!l z??z79OwQz0n;ypRTWFzyj~kzHBtF{l^?uM#@9+-4>wnD89vh1YQcqU%+l>5rzRV;U zX3(dU+N){NdCA1Og45X<4 zfVjHT9 zuXroTcv*er!>&h{%iEG{_)XtimHG7PFr5gja%1jG%58l3T2=^O5>m-7HDM#l1xP_Qs&EV*% zHB)G4r=lR$9O*bXY)%v4+O1L-*MI`Fl~@~GJDE#;@p8`iV1rw5^b;q8ix zCBS83zxLEQEiKbugUJOzdMc()It zQ$~9?a`86BJzlI+WBF^fbl>X;cu8Qb>(u_xvT&{94@Ow(jl$TpP8#X}xDRXEw2+W|u zuq2=}EK6?6m142oemr;BXci&G*xUYmV?KW9?(zlgUC&J5wmhIB@3cEx&u5OF^TuWV zDDu4&e>ihv&}`2*ryS)lk?7ZFsWt6)S+tpB`Z%6%U=c(=a3uo~FfgFt;a{$Fb;vPc z=`8U(`I+iB{UVe6kwAvp#RFfuI-WUNp2&w1K>D3mg8bbk7@p6o<>jq?8N6t>8la>v)%{T$1q=an!P5Ji8?}@QrL#Ii$)?sB<_B6+RR(cz1 zn78I@v<^aWO`v%lUA)N$S%zW=0xBvxbBgH2vf^57k~fi@%KqzG0+iUj{@dY} z;#+~0WP2A-n7FyStE`!CMKqHO;W>gs3xS<&W2QIwYiwc6*GS>YWRuLwM z@OvkC$Zy}lZTvmbmM{CiBwvu{ZXR;mq+wUGo!K5$&H3%i_vhVe zF()4FX?fDU@_&mtyhgk!IqTpBwjN%qX*qY1LBHgILY>EC9EJM#<-J*Rt0?3FB3UkP z6c7RV7@r=roagGlMueI*s-&_}&VvK#_U>`8V~g5*`nM&`DOQ!r6oYZs`TXPP^C4)W zk=rT4wOt3@As959Gd{cD-6LyC6HP+U8zFvc9qu(fD%D6T8@7@HlKf)*I^cR5BI?Lr zl$R(wOSC)R@KkGo%=39oQIM_l zB+a5VR~eFz0;)92glj<;IuV;YJM_yv)YdWR;QF|rNUkDdAPEsZ=_r$gsi10W;3 zaNx4)`&QM^VHw3%9cY?RRB!*p?59vUprENP=x|_hiq=4k)q$HdMpLNZ}D&4^$RKg|Q#_0O@*GvX~wy$VQ$xY7I zyPh_T|9-PnVSWR^bWPb6GWKM~O^eN(_Fh&{968&apRs)FC@5Qd9jNr`asovDaUF`1 z!aP5@esOzga;KGNx5}WA#weJm((H&-=>CY$U9^dgvR-Lsb0DX}bns)?QU+IyN?4M@ zW%EZ7)BllJs5uartsGpD4Re$Hzq60%svNn0;|7C~L_P3uO1uHXnfIGchjYK-IpHr< z5JZ=5EWdyh17AT(iZ|y9uT?Us3ZrI4XaZMRsJpuV2^iZxI!b~N`zUHmFfb2|>Kx zMHg~dE>3MQdVQdpw}SSE=x{wZJWimrT5X2~6sCIrLewzONmn9$Js>>XXQ2Hri*_TGH$cjTl=gg8Bm*U31#k z`1v$C4-y8UR>ocBVHmF^S5> z7>_jPELB!h8-AG_oD{V6+&Xy8HR(^m@_1y(Q<(m9cdY1FtVSk)bQ`~S^=MGzcs&HK zSLfz#6?%D+F|Z{=H!>=Hc!y1Oz1V3BQC8J_yVbL~2Zl;BYdt;1@Cg(pPQMOZM-SqK z^rj$ytzRkAG~2ImwwyBuJ!}-E>`z?1*=Csj%RsmO(~y&#XllkLc9t*xU*nJ%=FEkb z2>vafzjZoL?o!J~xtTlM-Ym7)G7~mm4v`=ffSifWWvkZ*ABAj5ag@NJuijwbIS((E z&p}*(Jk1~CD)h|xy)`nW+VrDuKg+?YV7^~}<~npf_Mqu8;g;`<%jhaf#wekF zCs01PUNpUVYZ~eS3q)61J#*0G@Lp&pC{;ftub{9S!QI|Ctxe2n$zB@~LW&?u#Ftf9 z81lnQ(%0!8s@+E!6O3LX5_G~X$~ia|s&pDc`iFunCOh^Hp|=BqqP1kcay0g1?XnPP zek_=!$;qZKIUI_D0<@=iEs$)dwTSRvU)e5MJluRIe=eh@W(%8!q{AYoD%Y2yAg~3= z2|3_UlQ?qkild3*U~9bZ$Yn&%&p*}liv>R@Z^LB{YAUHHy-k1dt)(z`>{G}be4&t1 zucgY2;?Kz?Y`~yF59T)0gN+gIBJTf_Erps4?M){w6o1(s@zja8$>gML&*0_gd z7n{V_`J`NQ-V88eLa8t=ePcr5#SawTRKL}P*hv3mjOBk<-Fxo`1Ntzi7PV!2%hgk1 zeFrcNg+BSl9bF)YmjezODk&JRG~MZb9S1C?r|$V|m0nah0WR%(_zlnfYjId2{kyQg zZ-=vdBcoHYOR6f3j5qDVnV*d|z&;;%LdQQ@gF0N=e#K@6(yy_EJaKIbo6DAvp|w;# zTPe$|Sx2if4-T*W%p4~%lVdDK>;xG&c9Q@0>LCP7!h80N3qXRpa35w3>Z|Nxjgu3& z;53BorUBHl)i}t7ZTre0xWpx8WnVbkyLL!Y;@k5tlF-A6ervR6eX1C=9w=nj`$o%5 z-+y{<$WAaiI%+a~v0k;_nyt?gwD#9Ht2En=qLkPdX0YQ?xxFPp;FX?+vC`1jog*FJ z)Wd1A(9?jp%L9kS%CA_iM!+dAczinZucIwPSQMjHTMo6ZTP}~NE?y35AE!FA zqp}Nc>_6_tK7G|brb9<90sq$1W~6)CB-=d2QVT4Y4~;mP=8#8YGt!Y5zh>Z73XoYI z!wvvgR_u&)&TO7-&?4&(MH|4t6D8pAB5jZtNa5OiWj9?rw$o=PK!oYDs3fk*l@sgu zxHQyoZ(aCg2gSIJbrZok|{U2nAyw`j|=WuNgn`@O2G-Qgf=w3^rTtxq{d$pJgs z<0CG9h!Ab^sh0=5qXys|mZ{G8DX=o8-GNe( zF%9YwQb_IjYndAT7;3K|aerY{ty<37EBl90GdjQHlgKtNhoX?vd~FNfOBLp)q!~*v z-al*80d^>8tJnYwcOHh zlxd6DdQKxOl(Mm&&ds^_S_?dsPw{REdVfWCGN5Oyw7R){|1#4d0r@!H#x2eoB!bi; z_{7imn8e{=yc<@sfZ=!6nj;BiXXL`0PLPA&=L~1N%&?e5P{0wQiU@`?lVn+VIr>X3 zsgxHZlQwrx=l-HC+fhbT@p!Il@3DfR^T}(mx&W==YIMQrgX&epR^T;XCHMQll0@)cpky75tCG48UD*FarEu%M!W0=mD@eLvvHfw9i`Q+d(x-f_Bxh}GaF%8 zCmymVJo8MI9a1-vr=!TsnPT)3Bkiar1w|qU^n!md; zigV{ZVh91f-i}PB`kU%8Be@{!-R;r?&R4HlF7eKCtk`9I3w5WA941J&if&}7$eHi| z0WYYlq{ZvqC^)7u*{Sm*MI560NKxgil9u~(ITvmAyR`D%@5?Sif0mXxfD1}^r=ZsvMmz4_+~!K)Z2t?JNgo3EM|IuTLu>xm7NJ45nh&(T zk6Y@Cwv4s2rOoX^=9Ft=!^$M_x|S-sn|4+?v^;E>17kD&nTOn1s6SSVgM~9ncsrE6 zK~KVgq;_gHE^~a;c@-)Wfb_H-!QY?V1XLjoTk$P)bbgNaVr=mgm{N1MrQ_4aj+_n4GFH6K<`*oIUuBMQncCx#~#A- zx`+M*em^X6d;CZ{cn!wdb9*xl(%ra#W zH;x;!oyp|)eSp1Z8LMy(TtfB)$~p6P{cWExY2tPstB#YjWC**{aohc*lk$AtsNF8f zwDH-}eKRP1@IsWQEuopB|OXDo%mTgcn+mCz+-?@_C5d+>kKlKqXQP( zCqzJnv@=T^vqzlxY+rjcJPqp3>oZDy@NtR>&vPSljx$kcEPjI1Yt6R;Ce>vyTP#Ut zRLhEjA1CPuru28;vIiA2_!Y3Q7xm=G^sso?1T4tzvM23nIVBQ-b5h!A>GIRM;)zWE zuLYoRb#|taG`g4lb>|Qe-mv$YOI}lWZto}DT>DsD4yU3aHIcpvMZt4TyEsGKRea@U z)byc7wT8*)Y;=h)WWvlh+T3c!_fg(~a6|1jC zQI-g`iivgx_7PpZ`(6%=w00HJ^><(nD+vHiR(e^JauNC!uY zUBJ@3M_j}I{R5)-70vA>16aZSlNv!gE1muExLIX7v7*sD=c+TxX_CkuwwAj5AZFOW zK2j7s*az@_ZhjE4 zaXRmeh{rB#XcG4aZYas2Z6~c!aE(f44rVA>s3nT%>N)$WzO`!Lq$U6HPF)BNprPfx zX_O2;=zhc(%+;Gu;kOz4Is~kG@I8HUd1mfx(PxDa?g{m)R834F2Y?6L^~tAgFVmmW zq(=33Co4yF*Ez{4mJSG&ZEOjv2U7UU1@RHmov^5}V;aY%a~xi|kbuGED7ad0<8UIy zBC4@Lb)%ZyeuXdg4-*#V*;0iKOSZ(eK2IFQua$@%--6y4%>)r(0==5eDQ&%K-5MA@_)Hy2PFEpVwTQT;TTKM=Xm5%p& z=K2h4kuVn&&~Z{~V8F-=Tp-xAp4}C(Mwp9o-Hjy<7(egO{(_R{$aIs+ggJKEY8;BO z1tST_=n?>R=KRRK`db?=tR6CPyjf8uRwqM;%p==lKQm_Wri(r`fc+}9=kwTglGjGh zo#WGO+grZ#3N6R$xgQ4d5>!gaEa-vl`hFac1f#8p;}f$ZPBbSTR6SgRKQhy;Vaf>* zPErAr`>Ob@{65++Omhew6@EGv8pC@;ipJs@@v%Ed}Z zzPFIlZ@v`JuawiJn;M!!T$`VL1tyittkK(6z=Df|T! zg-uR*s6tY^gyjLP@KG(OZIr>H0nzBmEw?_eIaY3}$)aPt8e~|+rhxwaC@1XPjxM*t zDNK}*G{@;4xA#rgxZKtH#WR=CQ?6|;Auy@?h3OgJmvjUcBrstw5pD9MPp_*7Q3Hwv z9S-l_*IBMN!({RhaLS-F@f^CvWd5KkmhHdSk{+3y3M=}>{7Tz=cv8zbw+BI8ivK)v z93CI2y_>EoC$8Y&~F7xdDal3(%~HMxrcP#bLD2tPX? zEnl>h8#sWcS#Ph!=+8ETyfBJ;r|7xAt`{jqfBVXDTkaryVM6S9!2#2)gY?f{*JDYs zB&@B>4by@-wAdk~1LaC8ovEdInW6pr2f;m?IQV+ahTeP5B{a=r4Op>Giu(0Z(;}_` zT8$Xo1T$w0d9-`?*1ZbRB$rGwQ8RYWZArf~jX$zY(SVK;L>+SvK8nF0pGAzllw2AKE2m#|!ta^DJ4dLJ!N~k9Qz<@25tud`sAk&rKZ+>W2e; zqJC$VvJ~fcxvbu5k_tzd~kbiRfOP40j9PeELHNr?O!eENpBay#E*Gnkv|p{S$V?D+o~ds(ZuLRt-8be8m2i7K((-%Rqct%M77%MrP-O~{ntBOr@K8sMO z+J`+bbIJsGO}vrW69lXGi9st6!~%P_fR~NcaCx{nkRj2(BAkfai&N;2j=fAsP!-#< z!$mRCXIl3K3K8uD(&L*qM?IVtFcP>uz)sFV7VMfe8c5(Q&*d!dI+p^1aQxGi#!8Ov zmMW@P6iv)~jwFS33@YX0T6-s{ZVtBhS+juobJY{cP zyXQ?GzG#oAD(fuv-d|v~2K*3%l;Kk}A~Bf*BJuyi&PiyLOg$s7~`oAztD1H$XXe(rt(*;5KB>7R7jIT&Z zC~SdYU!8|H=A}=4kgJeJfG+iXhZ*Fe?)uSc2Yrg}dhNrBbW4EtoyRv`4QY$nuc%^* zv~;v4yNlV|Jq0>AxR>E%a1p~gT)HD=`R|59g3l+RY1GGG1G|&=2}TWONAFT7T_~rn z-N4mGO+|@F*}IT(?{FABtoNEgE@oxyi$Vx36|{~?xbHvSWf00n?1#6fBUs@?6*c@= zbBQ3yORnTJ)k69m0V;yv^%+KZYxK2df9N&G08A`FT)_u`7f@Wr9Us{R$*Uo%@!SB`?k_6Ax;CvF6faMb2#Enui?d>6HO?l06V>EHqC;j>zOgVoEmN2r_pyUKT zioe1R?(P{;ISi7>%YW7D>JAflMZ4OT43b$|!B&=q+i+@aQVkr&q~5zuU=cHlD&%;Q zTIv6y0Efs;HaXG&yR4mVVp=6!lfJX+S3&XaMA5dZ4D-)Cx;n(uSiB$840z)F!?){P z>Ejl3dOZKDfln^-_o>~Y9e_;MaLBU< zc7nYu-!R=1!Zzm8f!S4sjT7n!#cy$i^QTWlj(TOI%a!}ia`za zH9L?Shg4hP)faDiZ$#X~3+nALo7wPaD=MIuV*W2J1<4=KHCcvkO1b%et+910v?0q- zoSRzv!qjf)X>lUiAGkX8LMc^fQK?WY^PD*P2odM%!r6oxm3%s+3M>(f;xy_pMQjO& z+vEnfvt?KHhk3Z}_ielw%OWT<{T|(TimKm|2E%{6t>{)phpIc48l91$=cBY`J|v`4kNokM0mz+VqSbUv8kyCJ}Y-Iw4_JQ7)w5n7Zua8^W+!)Mw{O4>YlE?pKEVSe5sUdrcV zL22?GHt37REqFw8^_H1i@8PXD&&LG`04N6dNX~)dTS!MVHA@z((&7?&Vql(nuaZjL z`a9&So0+PQmR*4E-sOo4u~$e+8dbRX4M&TQAX2NkbxyJ*Q{|oH4LHPNqkbB7jMn=}ykrM5Yhq>7F*ydi^uWs`bXe*q$(NrHA=Z zSp`0B-DGo=KP}@N7{>++c~GJG*BG&SP9D7J<#T@JROif(ku|9nF~~~D?Czg}QTVKW z^<`k`D5`R??i%Q$@9KL2yNTX%>f zmAW}F$(UT2XtH~XWIFfnG_a+9Z@B3{XPJE!LJC2YjgUukzv&(nk&AGhKV zC~)80m(z_+(?+M*6Vr3VRZV#{@KHZAS@G||mhjgP)2ESS$-_W^Lk#YlosGlVd7F60IE!J2O-bGxBMD1sHh$Jk@=?thcvMYd>J*g5t#GdF6 z+Ht^_b~!fz&dS3r?eOCS_)!pM$aS*W?EMr+J052ybiJxc72K;eXhsk+^886H!|(G5 z(DoVMMGRPg$Yt)`sIN%-gEl!hIxH(I)jM8k>HcsJ%WC8yytRYI#4Otv&J6YL7ma!# zEkbgtEk!|YDSW8L=i2r++_aD?u-8mVHpR_wLdCw{#O%A&cYpo3%nM)6{PwPD19`Ta zyI))^+qJ^y4j&r=U?p<>yzoy=@YkriIweJSur>)?>%IpKQUC*c7 zgODJ&XJ9{4$Hv{+XfhMZZ2rRL_S4GK9uiWK6T{N<4tpyrU3t0F8}GJTdn)C;qwPH( z@9EI{GgZmiQ-&-8DmBXy>M+-Zo!)18B7p=1c8Plx)neTi%^Au}dvf?6;2jtu;SB3z z;-USfrmEO)G~JcRBKR+_Fb_Mf=8L3K{m9`@1ZMu~pj$hm8EW~&SH3y{;%NFGliGS3 zGAv`w9=;!HYwous*bm8fC0`JEdUI<8a?kl5>kMQN{~KWUD@^V)gMg~2&9q==OB_Zw zyLsAPv#%a&-ch2fICtY0T+?MHjwNXUg;GT99h%H?2&KMtGThwOXUYyqhrE6~^D?>a zJSH(Nq^X__irCW zQVxc=Y0Ta4<%5T(R!j9p=-{66y=WEm1T}g@hQ`|tOuRn?PXdWBXN=Fnse*a_1$o8k zipOXvgA33hcXl`|R6!LGcXOvKzge>8HvrJ~c&%pC3V{w#0sXVz?NX4)h^OoycV^aBzbAsAI)N zTdAS~Nw}Jd8~vuh+>Du*^YAB^bVbQjhlU0-Y_rruDXhaqiMqG4R&>m1q+Y|=Sl>ln z4qKTXp`X?3fA2=a7Y-O{OTvcZjY5?G%EKkr9lrs|ltNWvSYl{|roecG4}GKKi2F6S zO*W~*QVZBFgw_-GmS8^p}vhK z3-Wn>rTV}0A6^Kbm_iX>RjAnBli*40nS8jR?l)Z76*ob`8s66*Bl087?i}=o8Q`BR zDCDCbB<%VdyE!YO4{s%MOQCq}>zC+P zJ8RReyYZ=s^E}8&#i<))S1Px$%KOJyweNNVyME&j7L^{Ci3GW5fdhKydbI zA6ieQZF!jsbNJVW8Z}#C&f`oz49Dw(6P(xO{jFVe;ANLjMniW^S;gPON5`ku0Rm~o zMQo(T&O@|+$S(t!Nf(v+TK27FE2p=&&pXLrGyU+2!<`qdFjokn6#BET@F>{7v)@A@ z2f`JNx7m%QY;d*Oh$5p$H?kp{n)?>FN87{q)v%hm*KPN2`7;U>Ne6qdS9nrp_PZG= zmAgTn?sVNfV2$w@^54c1Cc=$+bz-bGu{NXESe0%|dgq!|2x{|S6mozc%@|F!6)Ft^ zlydCX;ED>?1<}k%mr$*ovTe)45`xQSN)>>~;K?LdeZJcH)T3Z;-l{@KD*ZzshClqy zMs@Q1<&I(ES-}2cJ${C`8xj!F=TMW&3g<0bujly_Vq^Yb>P->sLEV|H-9P*9JW5LN z5jh(YwLA;u72V6HCfQu@_GxjDzt-Qf;@u6HfpjGq-wkjJXnvUPZGD}m)KzZ!!(C-tiZbYs(^*%k$^A{U&12s%DTp^p&oBOJ*s2aKkV z8xi7k_R8l5I|Ubh(5iMM0JLuCLOJNK;M^en@7&?XrW7e(sQ zG*c5xDM|GAa2em!W^%NzkVeHBs=^5NX=2~x&wMl+Y_7Ma54r<<3|Tdc?DE!<^1w$j za$*9K9FG^fZ};^NkNdE51^hc6#ODmtG-+59Tn_%bf1m2@hTeV6SyfJ^#I7)u>TEb{TPJ4~V#nxmqB3LRGSImDjGm1vWfHvrZ|v_duQo$UhC_kHRbDv zrqd^r1%EEKsUKLc6;p?O$M1rRLLzckJYFfiVOf ziDQ<0;LhT||JdqG4W17JT^xY)#_Az6)_09XNyLz9-#k;iM0?lWEVkQ@sir1pE)Ld} zg8bMXEi#H@k=|d_o1wi6B}&tx_~UbB05pDwr0@Z6_e_5uvx&Xr-t^N`{yO3R0L!U8 z%vvLwWXhKxWajx6$*JiBg`r=5l<6tFXtje+H3%eb{9vdJT7Sl=T(p&WehbBciC>FX z9yw=&U`2Gd>^(<7_DIN6gr1V(vezXV;SkFn1nEd2R@++uP&rAdW=~nL(rQ^w|VTOjyJiFHSHaeT4>gaw1l(T7F2t(&Hr+BYo;! zC)Cb4-m-ZKNU>D8+XL|-AzJG2scKzJO~X)>kbP!O-Hx-D791nbS$0M%2vxl4uI;$L z3CusWw*lP{3ai;FoCjDqF!fcxj(<2oC3IU~c-iW36w4f9M`+QcPn!Cuw?Qdu66n^X zIs-xVUFLjzE@%3nscaP$mEVfG@+KyfKE5~i0SH;i2BrnGelS*uFd8Sy$ zsqi&`Y-&}{pKZ)a?$YGQM#zH$6l|8)%V^ zFeYb+?H?k7-E;%m&?6Q{8jHl0S>KobhC3tR*MCVCSNU%tEVya}hkgqt>$v~J0RUX{ zoVT7Yz`X0?^xzGrIPH%Y;w?U1Bl3MeE9sD? z1)lhs89ynvhfbJe*0M9Rd!5UJeHRw5J=P&j^l6Tw%ZL5z^%avwMlNIiX2mt3`gIf} z&6yx4yv&hYCM=v3{b~Aua8A0&zL*d5s!iul$PO%=9JB|zaG-P*Fjw14LQ(57xd?aQT@uuA}-4v{i z$y72@qytLU3TwAYHZBjdKV>g0BmwE!$r}f>&0sIdsqb(rMVt;7BoEC=G^0YLEsgly z8(UdIB=M~KMr;NJ_z`4FrQ;&#V9G?+LSC>?Sy}mfm#BdF^uFgh+JE_oi2{cK11Xha zmL7@YFx~wzUegci&Wb}aM^e-3WbeISYLuP?O*qrf$Pm;>1N%*`2GkJ z*YN@S90&J27vpDerHyBR+=IGuRSUzdxet?BaptVpWRL&uTz*g)0P0_`2zL?&li1(t zAW7_PwwB9Y+Y-93$kccfI;Q-Bh_!#|5#g-MY;tr_Ta6_ ze5K*AR8`6H=$2fdbW3SE&+o3<##fE&)l!^kV9BYQ!fI+EA!`U*x{z||o$0ujv&4q- z>YnHxcUIM+uuw1%VBC(2Q{7LiThax+38<&I<9*&=$RfUrCnAFPofM%;w~6jRdsi#Y zE15h(J3jgE*@V-VR{qXoyL#nasZt0bRh8S_%-p`r+yp8lCocT>0wkS??3}dbI8()~ zn+cSuaTfAn3k}>dlovt(?{}8p%nkLrVgK|==OjsqA#+1d<_v$_bQrJ?udFP;hbVTL z07O#EwAg?BJDOSZ)5M?I`@ZoFWrodtU0eF9oQ|ZU)9dJt{a^?3=NusokwEqxu{Ys5 zGp!14O(m0+?W<;n7>)kX9JIF!WKI{~mD(jVU~u1o)%OGHU|O%&4-%UDC9M#j*9k$j z5?3Q-xmA!;C6}alP^GW?Gp{133lM-*;rDY%m;%Z}SoBNZf9-zM9XnWWXOzF%FJyUA zW?qzBq@|eXAxpZ3W@ZC|a!A~Zb^{cTy21Q3Si6qc%xtv!4G{U4d`=b@|4Tge52iwz zv1EUmR$AVq;|gi1NzH>R4us2C@0aT8j)43x$ZbeqmN`AsP)0;K^}>nJ*Qz0aHy%if zL@a?y?8%X@zq+@KP#@E{0nO@k98%MW&~w{c;eEPTZM9Coq_TK=zhuQJErWiAlK}(y z>pixjj1KoNgg?$0JnT>EuryK32Ac2R?X)w($)m+{>Oj{q{R`hU<0|4rstYJ^Z}cPT z;`+F6e_g+3R7Kx&TOvI18{7O0lV3e}7MC zz#lnhW!jX4${S`*PkS}Ukl(ijycG=t+ZBYt!oP#2bRQEf}b45#ZX3XE)DODFm_wmmY3>vw!nA#=1Wx4 z`A6=8FxqcAu%j7C58Gh3If#iKT}PEzSORt9of0N{6g$_U;Ot)t+`LMkx6-^At>Lf7 z6cd}#(Vdhm25{GPC-AE1cgr@{MoVq=`hpWIf+k_^e4 zjwt@i2=@Y!Mpl1ZT8Fm0LPW=%)~6*gj#-rxt_gC#K?_g^q;Ic{1NAIJ5n*;YyXHNI zYgBqc3jUiqjusYIAPg=n{eGhKe;r+8blhDNj~g{=%qH2`w(V?e+qN60(Z+7f#Bv=fgW_{PD+2azq!sZD7Y-v?)g$pQy_bnP3 zzp3*VRMGpK*|~x>zaV=MZ-@!*-!uN1m%(xa?`-s?g!HgCGVxPXmVp>Sa7ABDYQW8; znwA}7W8!U5RHV*R;&Yk>#&s~4wCF?8?UBI$GHroYeu{M2$QmW>32ewPR={Y3Ix56b zOB(t9Wp0xbM*x@(;tu=zqbfBjby%PslXG`;ASq9!?PjcS)`nk34+#OXl)cJoTTP&= zzl8kc@VYl|XttXH6%o{R8?ZMKE;T~@t!`!{iW%<`Fu1twTlpE@{QRGfDX}%DB%A@2 z!zynY#)lOvTX>Oj7Gqua+}@tzRG}ZqiP_mkR6L?@7`2M1E$ad!c?M{Tr~IF6C#pdA z1Pk@?({An0!Lup_J)}(na_fT#yqPM(y#lAtFjcWg5ohk~?c_8me@v1*d!Y(C*K4j{ zC=P!?@aZoTDCgXIC$wR^V@2R_b=9&&C~gA_?J%`iOyuDmC~B9}S3i>;s&w^os1s67 z_WnDX`qT0`I;&onN)dIZ-8x1XAX&i1p%{kr-q%GdWADi$z`7}26oU$&&JVfGKxL?3 zTiC~UfH-fVP$xx_-f~45x>k`Z!yhKmQTBGahc`e1WFR5xsK-hL5PQ>exHjGchF6bv z8$+4NCgiL9w4RFCvNx%7?RRHNa+SdmeBkb$F~Hl9@JQfeMbQs`>cUmPIv5{OR6-Ei<$c~~H2@mnvWc=o9>EfPngla0#Uf`%b{pyLm!U{XG+R;JwJ(HkKs6GnmZ`WehXSw`ccD?+ z38G1mFtM2cRw);F@&+X2K#v$sB=;~saSxtY_F%`&TL3`+)&|neb>@ay&GH;aKfi=wK?0gn96vMb z08b)Wspn)e+^B|n=aKd*fuagha)zd|I0(2M@ME!d<7WFTZgxj7<&o1|qN0T$%9Kwr zOtg$Pi7xgb_|xVmzU??%3zAOMi?;_0)i+^r;7z=^+;EXSky9Y+IqjN7Cz#S4`^}z*tS( z0?ejap~+8IeY0!Mec#6B-D<}|day>0Y?pR9Fsu_*92oosJ7A26->HSGx-xmm(J`&) zglY&xmf?!?RXE4-E~tnmi1>}>^JvdLBZgJzF1u8S#_9zyyL1pZ*^u(7vcH|*-AVrB z7)85UX`<0K4%GZ(4kspxA*CTDrm2aFAas-$Ojo)ga3hEkdXRyR_U^qrG_OMva*ufiJa@kcpn1x_%Nd`kPVCps333bgSIm4scg z?Lsp@ca_Dyb^hH?U(ly3F1%>*8~ZkCE3V6d=g=vA_!}H_-kgVQ7nW2W>70r9jql$- z7pBU}xD?Ip?nbH+U=rrT4lG^N$Mcn;sse2`ul42dJ;gFkA? zO5V?pzgQ;G>Uw(slU$^xEuxoalgvFKw{|0RPgR`!qpybp-ML!$?)`|^ar0uiA#cO2 zC@CJ0RF5ED=z;=p%qkQWaOlZvZBG63nDuksi+{+)RzaXG!i(RroHfD;+on)d7ZxBo zm>v&j(?pkyC9vtJ`|9N}^S(EJ%lC(`(PC1+wr{q0Y-w)AA@Je!y=U@i<6|5)clklD zY*iikCHkp#&xY9d)PSCN!B#&1q8`uSIrFKzKWJ|P_o}mpbVFO_@nI9*tt!Dw@{5#| zcE)N=S@Dl=7l(rat-xX9a>7Vl%R&$GMVt3qFS-$thgaV}A=?t|NBRCpQ4i7sR!wZ) z12B-9_ezb}wk^M$+h6jyeEN{W_37q|5zf6K5}ZTNouZM!PqqJ0GXigjI^k6B_kn83 z$zauq?Z4q@Ph%-?-zgROBK2h4+Q5{sDwbFKDVCdDSwrTLaY|+M;rxPShHF}5e{J@a z05vT`IFl-ogT;i!jZ|2BSFdlx^UZzJ4Qm}Qx78I3sbh~14>wH(?`@aMk)xwiTp|Gn zX>Ze>VAq+Khra>BggHm`zgOfv9humaCaR0=Eaaj)6w(`ZMrVhTj>{>&oZTn*dIrW6O5TMC71oO7}OGCXgXXbQD9Y- z4AqTF-R#b@`@J#ceoQif33RU^R)Nzue)jeb~W8qRZ!XjvuVt zb`TLJX5@E5_3+`qot=H8s?JkGWLw9rg*!gF%P}+RJM)Qsmc&QaVQa4S-&tuN< z+}T-5LwUvwe=IwGtUKvU7L@?RNk#`VTh;qn+7@SKhLg7x0M9`F&?X39eTZhV+@sxg zkdpNwNgq%DqKWR0TB;0X>f5f^s76ld=GE79qw-`YJskwPO!jRn{}eYI#=X?NL^ zuCjLvyp;9fg|&6W*Ue)jMRGSeD}bWSS&KCx8K7rCo*3A%0^xWOaZ&wEM;nh-&H;XV zS~r^YmuA5?TD*8Tm-?x=V5%Yr{9O`7u7MbKV#mK=T0?K&qGA*-m8=dgg(@BXb=yWS z)AvOjkbcurfHtNW_g2kB0S-8)J`8xdip2AwuIM?HUgAXUVrpc(yS`dr**0<6?;|HB zNca`~K$#NodKDx_PdcP#6l31HQ{qPg3Wd&l+w7of+^rkiwOSR5j3l__u|FaP(A95P z%oGzabGhmk^^DRTPJFMI><%XPu|ZGAvJqW9JEF*pHX*!ZL3HT+Xi7EocpeuhZ+MB+ z_jGqL3i4$zG&F>J`@kG450{{ya14W@CXAFg7P>6l6Y_M`@7-<=`|}b59VlX5DITRC zZ|zCnFJU!?E#($MBhgR?%kbk2TO~ z?CKI$YE-ydS6j^ifr=`50hLnUqJ^~_PW|#DSJrJok{z>j1tRaR!ZnRzv&C!~RkDguZ2734s1D;? zF!ZY)ErUq|Qqr~O86iMkv)YV(5Mx{WIe}|YcM_wjB`JjX>@ zC(DC|Ar+Ldsft+02*)RvhpW|fhesl>1Yn~;uE3tt-ytr3JG#l`@k;5S^VfMwsMKjs z-1Xb^sccqPQ>4+K{vePk63=fb(qLj~>SuM)nF=TsH8W?-onc=slu1-ci=sf9&rb!Z ztVN?yB(aP7HQaXDxZiE7q`1}QSdpf;0#^^`bX}PAAha<|JBHNqhs++CyFhH@v2UqP z(sI-(K7w`{_O#(TK&y|wpm+2>asnhXy6XP9_TL^NO#41?bb{yfOpSUv7HYddR8kJG ze>WJSa6FlAL4qVY|7v%nP%tq6431kSn_+?q4Ypj_89Q3p)qd+Z`}t`b%}h8 z)!WwZ(Kyvv5Br=%1HAo(u&8@|^Xrm`7oyD)s=naA9)x{0X-V9G!G?9@3$idZ;RmI#@WpRXeN~GIovRsOfk8kp7zZN4sIBYhjs5FVu$*&ow&&8vyxb=ET ziXiw2QxfIi&XBJzM-2JdqpGERrH0S0ePobk(t!ibV>pBi*DXO@UG)hzaD~Ww1j~w? zM8bg+qnsx`L#3Vz9Q%>@X`)nCwj2RB-O}je&=D>_sNE!DIeEMLmT=>aCf^4O%D68m z+Fp=!tf1DD&fc)9Z`LA=hwOt)l&K#pj+HwmsHeKI0j~BJnK+Q+XXdAMqr_)asn5t1 z9cyPXP$IuJYoSD*qEKqNMCzt$zYN29wpY$ooW?v(w%FP!BoFcxOUVe%d|?ruZVm2@ z_qG)_qs zOa#&5u8A-%JNSk;&g>)ZqsiUa*JKg-<(Xz-Wag}Qcd}}`mV1mEX!KH{o(O3+n6UQ3 zbLj>|q#QZig19=r=oLABI5yxXiaf~}y{}p$^}X$9);8V31k%+eb6uUPH6<%~5fwqo zfY#b_W<;(KB5`vf<|+A>t6$6X9NXCJzqio;BSFl1-c2mIQ{`Cdh3fA{NvBvI1$ymG5)@2r6G<8U(b8X#r?y>NzLpPeZ?nqlEV!`po1X^sI3@MF*05`|QeV-zKK6g3yLig9a?7S{N zZU>V~i9>Y#GfYo`FxI{gw%q)=1I}pr!FPIObOgocd&4&H9@AlfRPy@810aNjsOK>N z5Lq4~Ws^qB%EQ2ygop-W$G75|3+k|O5Bd5%t_#!=+4KF^NOh%Nqt|ejfJ~SeY2dz? z*T}rm z76O?+hBW>L?M(Lc3;fVe+Z&%SNDD*akjoimG*ay~^y=B(Bp<-kjEEp2ZS*5Mu~G;5 zNVlp5mhKn8cY{Aumlb^J1pr`E6c3m;xL5=JMlRwo$QZLwe*5*XUy;*a}PI03{uF zBPjFw;fGCU_b<2sRq|>H`5V!%gVqoPSS-?im#ia}0^MW+{ei}N?AD5#D@TMgG0&hs zgfa6T%4+C)s0@>9r8)*eygzctaRI4N)GR(|FbSnp%`cf&+m3fRD*}C9Er=2YJw)_B zZk$hEMuf&mUP_uhM+g|f797QMv?^~mNN8^dP*6XW-1*){8SY7d{@jjSpDAl`z9)_A zspJ`2fji`*u&}&e!`7Ds##44|Hf;e?CZyNVlPjx&yZPTYL9hXz#%;S2>5;ddB5sw9 zoLcnUcMp)h#n`2oP0$c5{nDe)s44VY(S=X0Wk@!e{16hn->7SPN?1b@zM};!IL~Y1 z9Y%h6Dto`Fl8Re-knHqPp$&pu{HXVomM7Xq8dfr5jx!%eK_bQ%Pj^~1yc_u=ad>xN zvaam3YAy2Y;3iHO^v>L$l)bjaUZNXDDhme=@5t9<=imeYRnV93*AsSoyJXcruncpU z(uzz|Q%fcV^=ewDGC?r|`zZm4>9Kb7cy-h`pE1vFPqCP!lR}>Yg*Ufuu@_lHrU~No zvVw1@v(LHx{$z&^m?Ujy_;zKD`)WCj5{J8_ZIQJs7l=|UfpM%n0U=SQb3!6{ zRaI5{OV{`jm1~yqW&G zU1&z%S%(y@_8PyT^K7}8x6(Vqy5L;Y78zRPU#mc+ z1WHzLwnBhJUw62vB;*#q;1etAi@Swa@T4k{*n3J%m88cUV;|5=id4l;^KheA5=Np* z6R+24n9Wbb#{WHy!Gyb1#g73;u_=;r|CD&fD<_7b6TIXn{Fa>Pa&S1!$+>TAK(sUE zdG>d#E+|dls-5z+R3#;9-`q<(a@(yn`$d{ZQ~SDszGoI(0DAUFRB8L!>PaZ(mkT{t2#QDH#6p`)!@;UI9qBl6>iXXwLb`%=KY_n;O?(~cFi;FhI@c82{Z77bbf6|x; z+4Zk%{bu|kU<1r|TZUTduKtc=_5+7tGzR7(JEYE<>P(S?9L0`bWhUU_!m(x{6B zngJdo4@{nQ56TRKTQNo|n_wbwUtd0+jQ|djPHk;@W|)6O?eoW(AYC`8jHVXSW%PYS zZGHH^U|p`x(HNFTv_G}F5&DzWI^8EJoqK8%yzh>q;*!PR!h-)jcJDW7F4Z4{?30R2 zOKhS|X63NNj3c|<*wd-6?@91kjVh|Dc4wS7Mr7*fd&vQWF~7lJ88whjw@<@KP)|>f z1MkuLxy_`jhJC)oF{ri?VoHWUr~q4!zE#*L2f7ZT-R zb5R;p*hqH9{)9_Nu?mrraJHCmjec7~UC>2!jmT>*=2QIG9;9($ing(D8ra*Rys0?F z^9<}h-2!$y`Pa#K)es*aU!&WV{{H%C%hLvx0mFymNQF+--jfeDm|0p2EwJdr1!8{$ zejR_Z0{^kW{7l13GYCzb&8{MbjR`kEE3Jq9ACF>v-Q0@FWmJZ*(Wuv91 z8G0(43#EEGR;t;gL9aoNDY{7NY2K{CtRY&5@$@Y0D+VgU%`*bQ{WCuCy=BnV=_Q4x zML;J;z{irl?yeh9UtfVD>nlELG_i#E##oWADe!Hx&Kq=c% zX#osAn%s^j00DL$e0`{J@5T}Eb(*k_Z*PBXvYHl`r*2qz0J8OM&8h^w z8Na<`^Z}ApB?c7?m_IJIu1tpD@vz_9jNDF2-?sl9Hj_HL@#!<2>`V>?yU$s(U^vws z5!n`P<-Y56rS38tha_qoj>^R278Kb?mHB`e8WoR^gAAePbX2vpq|bIo7!5m9shIH; z3>0)aJ?NN}X|%qz|C1cDYx&dZ!xl#2E_|9Q)b>i-7P!+oCG0-a@f|ruSHx;WcP!E0 zUAEU`N1PiXMs>Zn@>XlWC*TbKDGa zwOAYm8z-l-E`9JJ9||woa^VK==GBz7>LjH|>igh8xTMC!PjVIftUD69(=u`RE5?wm##kpgfwH3VQcp2L~$>0>WddIw&RqMdWr? zv&Dx+ee{2M`<|dS{99pMo}NCwSx#o)cy3gN7=XZ5S4mHQ8#|>bdM-L0Aw>K9)bke< zmn9M`Oruhj7A=!lCM^U|8bPEY!`Ky`X$F^Mz*4uYx+%{4@zU}tU#PjQ?M#?B!en}t zOF9P(fg$|R4@j;62n@-9s2=#!-$i8suT`eQsmfK3%|$t}MHqy~)TBsiK>fs#L)9a! zES)boRtv`ZIh9z~%@RtEO4J}WwbWn0j2t+7dwYp=O9^eqcika(NtOKbuefnpogRUK zfp5DXufC62)+guZtl!}v65Vj$JkJ|EgfO#JAIdQ!D8VCb7`L=EqM@aA_}y2MtLo{q zP*(jSgdlwTZmmvmMsT-}I&wFNt+6|?%?+(3ROXm(1iswRanq5DR%2$~CQ4tn?7U4} zH7v^T+f>v+M8Nji)`a{^(g!)x0zq6fjJSPn3>qvXegT0j5fSgf;gf1@bYp!WFT|D0 zpj``~lGEXg`=!G;>fQUm#INjCZ!!RrJCm-MxnS1<+)`ChSLc|Xp62A@fm~^l>h2ur zf(XhOCI`RL&R1I)UP~v)`5-qK-?>|>QM9~=dX%>Eu$av4pVA01@-)SYw0O*(@84}2 zC{~F}c7dzq)m>&Ggwwkm{yTJ3X2aspyE|ViEr>_-UztS`L0=wDpyOSF0@k^b}tzc-*40u zsHR)}YG#)=2E#{Xnc7@dO~n)DbwhCT^yT;r@Owk~UkoK`GZ`iOa>jFkeJNivt9}4X zjgYwx%wC1SMMk1KdPu4wNWN6Z^W{XEMccMOQC@KB;^7`9!-RDLW*o^h=8L2o6uF_9 zKfUhlYPKmzp#iZWBvFS~^cNu5q$Jp9-CocH-=xI~+UGoz-a+%6qEQF+CtEs`z7@88 zK>!H0gvy&`OcYm7`B<*@yE|V6uEeSCfC)yQ$iMZx%9!*rs{B>Z1 zG{@)LouI6Iqs1qc1dfS4TaW;;S9Xs3OV&?jYx~0#{z}_UkAh?8&^p_;BM%rQoy2k@ zic5&FIOX~h7HJ8LH9^4}4v12-6i|WD21)KeQ%p7%LON>{pD*|3@of3P{`*lN$sU@T z3h~^Wp4u5G7%~c7a2hCNG}_D+b;r$QmI;gl8Z?lGO+j+`(khRU6ZAh|JWhd*j*c}3 zE%dXS>KF)*qV^LgmE=5b+P4Rvv$G?M2V;x2@1AXJY<}a|Jv=?#UHo&$lSw3{%2G^H z1jqrf0HBGfJG}hhd`XJXBHGl9jJwb{mcv*jNGlk0BYCL<7xe)4tlyRQS{nEu!8>VX zc+k@%`iDpXJOP#;V%dvhHrdd4E1uR#6EF z*ceHeCU1o1IN)HJh&#`0k=vRYVI1 z>z4)vtMHM~>T5=yBq*Z_;HpGX5s-LcfZT)#6ATPd932tOds)eE!$?E8@=y>8F$Dzc z3Gp01aU2tU-6jKIqhg>%MN3l*o3nvp;6Q+QUOs-JWS2}0trbsi?}V`~nO6(>P6oG` zLH8mjc+JHnD;ecc6#|7?N?&NtXRE4SM;bS#jw0G{3GxjtgcnT((wK0LlmeOVGFpmg ziXvJHs;CN^7mWy=zU0|HXTM>wMq@K zY`U-*)aWI{m=QC$_aN~Bs7A&!_R9D7j=g=EFviKRlfDP=@%8>-r()-CbTYTZV@zX) zS)v8R3&-O0?CUxL{$4lYnd+a@($e5ypf$0~;Sh1F3kA1gzR)1T!=R$Qu)Cg;+YALt z2tP}j9L?mW1|`*qVX6<%%*NnZ>ARIm&d(u7c-@=`yIF|W30Y-o=vb}Cz)-QneM4}o z8%{Tl3u^QpRadt_}@7<2|SjEQO!Poq?VT0N&Ruwq1VlRY!NTS z=@Se%W`#s)Kf;ZI88MWo1vSbfT*3@=hzf05l0o;zjSxI43$j>l)QYCc0L0jE$}{3l z3YL_FhlMdR(8hlM8qJ%>q@k%vkZ+C{TXdawwXQ^4a_2?0?Z5J>%s;VVl(_5GN)44q znJGWoQ1XRi#r5tcGGRXoUFo=G40+DNOkZjhGzrfgULDjClw3}WEF>fpY51@L=(|8^ zvy3K=uM$zGJYKS{WkO^$Xir+S*J`qzr#7gi;(L92(e69U>$$RU{>YotXqTh$CFBES zcmfLWHP^^>8X2EGAj#}*nx%FG2QWFE(}U4@d3gk&SA>9Whz;qm)tl%2)R(gY$xU6q z+=Va9&d%294Ir3IXEJ||J%GR>&J@KzyALFFcfTe2CO2!KyovI>tC9pIwGNj13%xUY zPKg;GZ;@y^vRAb|VbIASg|h}2a1wdh%>qeZ*u)DlAiJ5$6Y$=x6_G|Ps)&uWQ>~PX!xMLF`Uhz= z>yO%o_wCm&d8g-fCIi=z1K+2+SJ?Y|kNNqHp;pJbdh;=~CRu&B_Mvk@^@#mQa|m<~ z|F`^#SOhOKFHWq4A`{>)4?hP?$W<*yj6x^L)&k(cC!a?*F_UY^;y1VyW5IjDIu}J= z4px+)*axY=s6drNhYy)vJ`V`}cPwS4r4he=A=5KJ+BGC^ZW?vY4<`^vx}qk*)w=o% zU1eXeYRZ04Uqd(H;qXb-Oe%D@1!kV_t;>@0|01vW1xv>76OC>VaMNy7m&zJjuVGh& z6Om*vRfkdsHCrqX-3tlgNPFDR{{c9|X2Gi%8ztnzG^P^834$x02Cn31a?yzmg_ z9z6OfuHnT)X4rJ+(|3j^Wjy5lLJa=_6(Fz?kbh_m1@a8y`XE ztP_nP+4KNZUW9ek*e^|=~bNcA#cB)s-Uk2(blF&1MA=u8k_c>uHN>C@B z15Cv5HZZe5eoIw)=MU};i(I%QLCw6slK(sqK{)U5mZ6sRQu;L6U-@$>{!ri+#L|i0*Q(~4kD@~qx4AoHc!HSBy@&UU6vu1K>ZS@ z$V0J5;Pvm01%$S$5>+RDlJkU6Z9zPMrqk^uf(6__-bRaOk_(#q5eU^t>_ zri+{Qpw4IE#*OG183h3d<7Ae)W4e0s|3NE%;^t6hTNdi_P8_pUKx-P#+^BWaPq&@~3JDWoD!=Rj`02`gOBHA*5$kF-3 zio_LOSMJYwJ%+1PiVj?eIZM(8zN1@6y^&rBdjXafN4fmHHVqpvp>uLJFy%g6%gcv8oPw)i%~FO!TC+M`7B)?l6CCUqUBW>|hUz zU-HqurUwm&mWOCv-1vK4S?x*TDeW`ieFj3jAZ#)R{k7!2>{*Jd4hTh2{p%g>oe5+j zg^o43S8@R{b*So+9ipP(wg&N*-RR`7SHc<-*v^wy!2wThMldY+)wXs8R z5-~4pmCIZBVCMc%x*#^{L4vP>`C?VtO7<5R7v;)J$09a~TR})*$#uK*{9=BqGsmGp)^+O$ISc%Jo=r9ug^FXw`j2D~i%zp2OMruUPSNw~66yk$4jee-r3YlC^9Uh9CTw-w;3jwivVK3DgZwRA zys-PKXDC_1E#zcwKRbc|gcnH+>T7hgOIbH-*yl9T)eToLHuA z2m*L@x8^Z$8}h|?r;~YgN$@Oap4Cbg&rQ*Mg*Y{o^95I09M6^#m{@u>h*06QQ`W*k zFw|az;xView}UsRx^AdztxkEnfZ5jlAwclI_ot(PdrEB*WdPQ6Y|#Qt?fnpHpNGFt z8B$5*cgQ{x@Kk^5joC21r6QW*~fA% zyfP2xbM<2SJe36}@(5f{e_{v@L=-BqwpPQ1-IKmo?*oo3!l#6gVM8;EVoL^TLlI26m3`c$@Cch>U8iWx(=Sz~1g9bDxI#M+z0tffV zx5=im8aSML3#nLSBOE#*E0P+#cnBYtzq|5r6i^GjV;e)E@95&);i7)RIGoBd$G#OT zl@s1eNkl`31)~ZfMTiHyW!v*Tb-U}f1qoT#>dQz-v<6K4{Yn^vfeMER4_h|8Gzf8J zEicQes3dybp-xyQeX|bvnlvY|+2>65`gAdQ{(INKbmQgW)O^D)J->B94dX zO<d4aiWuN~c2}9v;|c zJHc0vezgqu&RI?nk)z##I5rUSnMXPpwNM_KPBs6`I{g>>SncGuv$v~XyMQ#<9xTL2 zwn?=CfIbMQu#mpQNXAGPOHyDC?zo6CE8t?A^sJp_y;R8+52H@V#5B_a@l-`tp4g?| z7A_tFOdFle1lhhA5>WjqlI+Vpf5nHj*d{9HA21ySB@#e9T>;zj8WYEpnJ<2u$k#O6 zT@ZeWpXkks=|`PVK+I@bOrWpyqIQvfIXV&5?cEzCko!Th9KrwiYTE|p=qbBOz=WK% zb$jklEe)y-X%p_>Cb#a#PlOA}2@;7G`CEGxi(wlT?uY)IedzD^5Y_yzZfpPFC%>jr WB|}ylEyzoVP;yerlC|O{VgCbbSQ455 literal 0 HcmV?d00001 diff --git a/my-bloody-jenkins/templates/NOTES.txt b/my-bloody-jenkins/templates/NOTES.txt new file mode 100644 index 0000000..2fcf78c --- /dev/null +++ b/my-bloody-jenkins/templates/NOTES.txt @@ -0,0 +1,39 @@ +1. Get Jenkins URL by running these commands: +{{- if .Values.jenkinsURL }} + {{ .Values.jenkinsURL | quote }} +{{- else if .Values.ingress.enabled }} + {{ .Values.ingress.httpProtocol }}://{{ .Values.ingress.hostname }}{{ .Values.ingress.path }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "my-bloody-jenkins.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 svc -w --namespace {{ .Release.Namespace }} {{ template "my-bloody-jenkins.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "my-bloody-jenkins.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') + echo http://$SERVICE_IP:{{ default (include "my-bloody-jenkins.httpPort" .) .Values.service.httpPort }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "my-bloody-jenkins.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:8080 +{{- end }} + +2. To watch Jenkins logs, run the following command: +export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "my-bloody-jenkins.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") +kubectl logs -f --namespace {{ .Release.Namespace }} $POD_NAME + +{{- if not .Values.persistence.jenkinsHome.enabled }} + +#################################################################################### +# WARNING: Persistent is not enabled!!! +# In order to enable persistent, please set persistence.jenkinsHome.enabled to 'true' +#################################################################################### +{{- end}} + +{{- if not .Values.rbac.create }} + +#################################################################################### +# WARNING: RBAC is not enabled +# In order to enable RBAC, please set rbac.create to 'true' +#################################################################################### +{{- end }} diff --git a/my-bloody-jenkins/templates/_helpers.tpl b/my-bloody-jenkins/templates/_helpers.tpl new file mode 100644 index 0000000..ff63a4f --- /dev/null +++ b/my-bloody-jenkins/templates/_helpers.tpl @@ -0,0 +1,67 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "my-bloody-jenkins.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 "my-bloody-jenkins.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 "my-bloody-jenkins.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create pvc claim names +*/}} +{{- define "my-bloody-jenkins.jenkinsHome.claimName" -}} +{{- printf "%s-jenkins-home" (include "my-bloody-jenkins.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "my-bloody-jenkins.jenkinsWorkspace.claimName" -}} +{{- printf "%s-jenkins-workspace" (include "my-bloody-jenkins.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Define default values +*/}} +{{- define "my-bloody-jenkins.httpPort" -}} +{{- 8080 -}} +{{- end -}} + +{{- define "my-bloody-jenkins.jnlpPort" -}} +{{- 50000 -}} +{{- end -}} + +{{- define "my-bloody-jenkins.sshdPort" -}} +{{- 16022 -}} +{{- end -}} + +{{- define "my-bloody-jenkins.persistentVolumeClaimName" -}} +{{- .Values.persistenceExistingClaim | default (include "my-bloody-jenkins.fullname" .) -}} +{{- end -}} + +{{- define "my-bloody-jenkins.tlsSecretName" -}} +{{- printf "%s-tls-secret" (include "my-bloody-jenkins.fullname" .) -}} +{{- end -}} diff --git a/my-bloody-jenkins/templates/config.yaml b/my-bloody-jenkins/templates/config.yaml new file mode 100644 index 0000000..31e6ea1 --- /dev/null +++ b/my-bloody-jenkins/templates/config.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "my-bloody-jenkins.fullname" . }} + labels: + app: {{ template "my-bloody-jenkins.name" . }} + chart: {{ template "my-bloody-jenkins.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + jenkins-config.yml: |- +{{- if .Values.managedConfig }} +{{ toYaml .Values.managedConfig | indent 4 }} +{{- end }} + + k8s-default-cloud.yml: |- +{{- if and (.Values.defaultK8sCloud) (.Values.defaultK8sCloud.enabled) }} + clouds: + {{ .Values.defaultK8sCloud.name | default "k8s" }}: + type: kubernetes + jenkinsUrl: http://{{ include "my-bloody-jenkins.fullname" . }}:8080 + namespace: {{ .Release.Namespace }} + templates: + - name: kubeslave + image: {{ .Values.defaultK8sCloud.slaveImage | default "odavid/jenkins-jnlp-slave:latest" }} + labels: +{{ toYaml (default .Values.defaultK8sCloud.labels) | indent 14 }} + remoteFs: {{ .Values.defaultK8sCloud.remoteFs | default "/home/jenkins" }} + jvmArgs: {{ .Values.defaultK8sCloud.jvmArgs | default "-Xmx1g" }} + volumes: + - '/var/run/docker.sock:/var/run/docker.sock' +{{- end }} diff --git a/my-bloody-jenkins/templates/deployment.yaml b/my-bloody-jenkins/templates/deployment.yaml new file mode 100644 index 0000000..a513d2d --- /dev/null +++ b/my-bloody-jenkins/templates/deployment.yaml @@ -0,0 +1,224 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "my-bloody-jenkins.fullname" . }} + labels: + app: {{ template "my-bloody-jenkins.name" . }} + chart: {{ template "my-bloody-jenkins.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: 1 + strategy: + type: Recreate + rollingUpdate: null + selector: + matchLabels: + app: {{ template "my-bloody-jenkins.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "my-bloody-jenkins.name" . }} + release: {{ .Release.Name }} + {{- if .Values.podAnnotations }} + annotations: +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + spec: + {{- if and .Values.useHostNetwork }} + hostNetwork: true + {{- end }} + {{- with .Values.securityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if and .Values.rbac .Values.rbac.create }} + serviceAccountName: {{ if .Values.rbac.createServiceAccount }}{{ (include "my-bloody-jenkins.fullname" .) | quote }}{{ else }}{{ .Values.rbac.serviceAccountName | quote }}{{ end }} + {{- end }} + {{- with .Values.image.imagePullSecrets }} + imagePullSecrets: +{{ toYaml . | indent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ template "my-bloody-jenkins.httpPort" . }} + protocol: TCP + - name: jnlp + containerPort: {{ template "my-bloody-jenkins.jnlpPort" . }} + protocol: TCP + - name: sshd + containerPort: {{ template "my-bloody-jenkins.sshdPort" . }} + protocol: TCP + + {{- if .Values.livenessProbe }} + livenessProbe: + httpGet: + path: /login + port: http + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + + {{- end }} + + {{- if .Values.readinessProbe }} + readinessProbe: + httpGet: + path: /login + port: http + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + + {{- if .Values.resources }} + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- end }} + + env: + - name: K8S_NAMESPACE + value: "{{ .Release.Namespace }}" + {{- if .Values.javaMemoryOpts }} + - name: JAVA_OPTS_MEMORY + value: {{ .Values.javaMemoryOpts | quote }} + {{- end }} + {{- if .Values.jenkinsAdminUser }} + - name: JENKINS_ENV_ADMIN_USER + value: {{ .Values.jenkinsAdminUser | quote }} + {{- end }} + - name: JENKINS_ENV_CONFIG_YML_URL + value: file:///var/jenkins_managed_config/k8s-default-cloud.yml,file:///var/jenkins_managed_config/jenkins-config.yml{{ range $i, $configMapName := .Values.configMaps }},file:///var/jenkins_config/{{ $configMapName }}{{ end }} + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if .Values.jenkinsURL }} + - name: JENKINS_ENV_JENKINS_URL + value: {{ .Values.jenkinsURL | quote }} + {{- else if .Values.ingress.enabled }} + - name: JENKINS_ENV_JENKINS_URL + value: {{ .Values.ingress.httpProtocol }}://{{ .Values.ingress.hostname }}{{ .Values.ingress.path }} + {{- end }} + - name: ENVVARS_DIRS + value: /var/jenkins_secrets/JENKINS_SECRET{{ range $i, $name := .Values.envSecrets }},/var/jenkins_secrets/{{ $name }}{{ end }} + - name: JENKINS_ENV_HOST_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + + volumeMounts: +{{- if and .Values.persistence .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + - mountPath: /var/jenkins_home + name: jenkins-home + readOnly: false + + - mountPath: /jenkins-workspace-home + name: jenkins-workspace-home + readOnly: false + {{- if .Values.persistence.mountDockerSocket }} + + - mountPath: /var/run/docker.sock + name: docker-socket + readOnly: false + {{- end }} + + {{/* Using internal secret - each key will become JENKINS_SECRET_${key} */}} + {{- if .Values.secrets }} + - mountPath: /var/jenkins_secrets/JENKINS_SECRET + name: {{ printf "%s-%s" (include "my-bloody-jenkins.fullname" .) "secrets" | quote }} + readOnly: true + {{- end }} + + {{/* Using external secret - each key will become ${SECRET_NAME}_${key} */}} + {{- if .Values.envSecrets }} + {{- range .Values.envSecrets }} + + - mountPath: /var/jenkins_secrets/{{ . }} + name: {{ . | quote }} + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.configMaps }} + {{- range .Values.configMaps }} + + - mountPath: /var/jenkins_config/{{ . }} + name: {{ . | quote }} + readOnly: true + {{- end }} + {{- end }} + + - mountPath: /var/jenkins_managed_config + name: {{ (include "my-bloody-jenkins.fullname" .) | quote }} + readOnly: true + + + + volumes: +{{- if and .Values.persistence .Values.persistence.volumes }} +{{ toYaml .Values.persistence.volumes | indent 8 }} +{{- end }} + {{- if .Values.persistence.mountDockerSocket }} + - name: docker-socket + hostPath: + path: /var/run/docker.sock + {{- end }} + - name: jenkins-home + {{- if and .Values.persistence .Values.persistence.jenkinsHome .Values.persistence.jenkinsHome.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.jenkinsHome.existingClaim | default (include "my-bloody-jenkins.jenkinsHome.claimName" .) }} + {{- else }} + emptyDir: {} + {{- end }} + + - name: jenkins-workspace-home + {{- if and .Values.persistence .Values.persistence.jenkinsWorkspace .Values.persistence.jenkinsWorkspace.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.jenkinsWorkspace.existingClaim | default (include "my-bloody-jenkins.jenkinsWorkspace.claimName" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.envSecrets }} + {{- range .Values.envSecrets }} + - name: {{ . | quote }} + secret: + secretName: {{ . }} + {{- end }} + {{- end }} + {{- if .Values.configMaps }} + {{- range .Values.configMaps }} + - name: {{ . | quote }} + configMap: + name: {{ . | quote }} + {{- end }} + {{- end }} + - name: {{ (include "my-bloody-jenkins.fullname" .) | quote }} + configMap: + name: {{ (include "my-bloody-jenkins.fullname" .) | quote }} + {{- if .Values.secrets }} + - name: {{ printf "%s-%s" (include "my-bloody-jenkins.fullname" .) "secrets" | quote }} + secret: + secretName: {{ (include "my-bloody-jenkins.fullname" .) | quote }} + {{- end }} + + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/my-bloody-jenkins/templates/ingress-tls-secret.yaml b/my-bloody-jenkins/templates/ingress-tls-secret.yaml new file mode 100644 index 0000000..fa6fc2e --- /dev/null +++ b/my-bloody-jenkins/templates/ingress-tls-secret.yaml @@ -0,0 +1,17 @@ +{{- with .Values.ingress.tls }} +{{- if and .privateKey .certificate }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "my-bloody-jenkins.tlsSecretName" $ }} + labels: + app: {{ template "my-bloody-jenkins.name" $ }} + chart: {{ template "my-bloody-jenkins.chart" $ }} + release: {{ $.Release.Name }} + heritage: {{ $.Release.Service }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .privateKey | b64enc }} +{{- end }} +{{- end }} diff --git a/my-bloody-jenkins/templates/ingress.yaml b/my-bloody-jenkins/templates/ingress.yaml new file mode 100644 index 0000000..0efa165 --- /dev/null +++ b/my-bloody-jenkins/templates/ingress.yaml @@ -0,0 +1,64 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "my-bloody-jenkins.fullname" . -}} +{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} +apiVersion: networking.k8s.io/v1 +{{ else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{ else }} +apiVersion: extensions/v1beta1 +{{ end -}} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "my-bloody-jenkins.name" . }} + chart: {{ template "my-bloody-jenkins.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- with .Values.ingress.labels }} +{{ toYaml . | indent 4 }} +{{- end }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} +{{- if .Values.ingress.tls }} + tls: + - hosts: + - {{ .Values.ingress.hostname }} +{{- if .Values.ingress.tls.secretName }} + secretName: {{ .Values.ingress.tls.secretName }} +{{- else if (and .Values.ingress.tls.certificate .Values.ingress.tls.privateKey) }} + secretName: {{ template "my-bloody-jenkins.tlsSecretName" . }} +{{- end }} +{{- end }} + rules: +{{- if .Values.ingress.preAdditionalRules }} +{{ toYaml .Values.ingress.preAdditionalRules | indent 2 }} +{{- end }} + - http: + paths: + - path: {{ .Values.ingress.path }} + {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" }} + pathType: {{ .Values.ingress.pathType }} + backend: + service: + name: {{ $fullName }} + port: + name: http + {{ else }} + backend: + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- if .Values.ingress.hostname }} + host: {{ .Values.ingress.hostname }} +{{- end }} +{{- if .Values.ingress.additionalRules }} +{{ toYaml .Values.ingress.additionalRules | indent 2 }} +{{- end }} +{{- end }} diff --git a/my-bloody-jenkins/templates/pvc.yaml b/my-bloody-jenkins/templates/pvc.yaml new file mode 100644 index 0000000..a561e4e --- /dev/null +++ b/my-bloody-jenkins/templates/pvc.yaml @@ -0,0 +1,59 @@ +--- +{{- if and .Values.persistence .Values.persistence.jenkinsHome .Values.persistence.jenkinsHome.enabled (not .Values.persistence.jenkinsHome.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: +{{- if .Values.persistence.jenkinsHome.annotations }} + annotations: +{{ toYaml .Values.persistence.jenkinsHome.annotations | indent 4 }} +{{- end }} + name: {{ template "my-bloody-jenkins.jenkinsHome.claimName" . }} + labels: + app: {{ template "my-bloody-jenkins.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + - {{ .Values.persistence.jenkinsHome.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.jenkinsHome.size | quote }} +{{- if .Values.persistence.jenkinsHome.storageClass }} +{{- if (eq "-" .Values.persistence.jenkinsHome.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.jenkinsHome.storageClass }}" +{{- end }} +{{- end }} +{{- end }} + +--- +{{- if and .Values.persistence .Values.persistence.jenkinsWorkspace .Values.persistence.jenkinsWorkspace.enabled (not .Values.persistence.jenkinsWorkspace.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: +{{- if .Values.persistence.jenkinsWorkspace.annotations }} + annotations: +{{ toYaml .Values.persistence.jenkinsWorkspace.annotations | indent 4 }} +{{- end }} + name: {{ template "my-bloody-jenkins.jenkinsWorkspace.claimName" . }} + labels: + app: {{ template "my-bloody-jenkins.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + - {{ .Values.persistence.jenkinsWorkspace.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.jenkinsWorkspace.size | quote }} +{{- if .Values.persistence.jenkinsWorkspace.storageClass }} +{{- if (eq "-" .Values.persistence.jenkinsWorkspace.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.jenkinsWorkspace.storageClass }}" +{{- end }} +{{- end }} +{{- end }} diff --git a/my-bloody-jenkins/templates/rbac.yaml b/my-bloody-jenkins/templates/rbac.yaml new file mode 100644 index 0000000..697c813 --- /dev/null +++ b/my-bloody-jenkins/templates/rbac.yaml @@ -0,0 +1,58 @@ +{{- if .Values.rbac.create }} +{{- $fullName := include "my-bloody-jenkins.fullname" . }} +{{- if .Values.rbac.createServiceAccount }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $fullName }} +{{- with .Values.rbac.serviceAccount.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +{{- end }} + +--- +kind: {{ if .Values.rbac.clusterWideAccess }}"ClusterRole"{{ else }}"Role"{{ end }} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} +apiVersion: rbac.authorization.k8s.io/v1 +{{ else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +metadata: + name: {{ $fullName }} +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["create","delete","get","list","patch","update","watch"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create","delete","get","list","patch","update","watch"] +- apiGroups: [""] + resources: ["pods/log"] + verbs: ["get","list","watch"] +- apiGroups: [""] + resources: ["events"] + verbs: ["watch"] +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} +apiVersion: rbac.authorization.k8s.io/v1 +{{ else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +kind: {{ if .Values.rbac.clusterWideAccess }}"ClusterRoleBinding"{{ else }}"RoleBinding"{{ end }} +metadata: + name: {{ $fullName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ if .Values.rbac.clusterWideAccess }}"ClusterRole"{{ else }}"Role"{{ end }} + name: {{ $fullName }} +subjects: +- kind: ServiceAccount + name: {{ if .Values.rbac.createServiceAccount }}{{ $fullName }}{{ else }}{{ .Values.rbac.serviceAccountName }}{{ end }} + namespace: "{{ .Release.Namespace }}" +{{- end }} diff --git a/my-bloody-jenkins/templates/secret.yaml b/my-bloody-jenkins/templates/secret.yaml new file mode 100644 index 0000000..6467bdb --- /dev/null +++ b/my-bloody-jenkins/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "my-bloody-jenkins.fullname" . }} + labels: + app: {{ template "my-bloody-jenkins.name" . }} + chart: {{ template "my-bloody-jenkins.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: +{{- range $key, $value := .Values.secrets }} + {{ $key }}: {{ $value | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/my-bloody-jenkins/templates/service.yaml b/my-bloody-jenkins/templates/service.yaml new file mode 100644 index 0000000..708ef05 --- /dev/null +++ b/my-bloody-jenkins/templates/service.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "my-bloody-jenkins.fullname" . }} + labels: + app: {{ template "my-bloody-jenkins.name" . }} + chart: {{ template "my-bloody-jenkins.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} +{{- with .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . | quote }} +{{- end }} + selector: + app: {{ template "my-bloody-jenkins.name" . }} + release: {{ .Release.Name }} + ports: + - port: {{ default (include "my-bloody-jenkins.httpPort" .) .Values.service.httpPort }} + targetPort: http + protocol: TCP + name: http + - port: {{ default (include "my-bloody-jenkins.jnlpPort" .) .Values.service.jnlpPort }} + targetPort: jnlp + protocol: TCP + name: jnlp + - port: {{ default (include "my-bloody-jenkins.sshdPort" .) .Values.service.sshdPort }} + targetPort: sshd + protocol: TCP + name: sshd + {{- if eq .Values.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{end}} + {{end}} diff --git a/my-bloody-jenkins/values.yaml b/my-bloody-jenkins/values.yaml new file mode 100644 index 0000000..3d7252a --- /dev/null +++ b/my-bloody-jenkins/values.yaml @@ -0,0 +1,254 @@ +--- +######################################################## +## Override image +image: + repository: odavid/my-bloody-jenkins + tag: 2.332.3-277 + pullPolicy: IfNotPresent + imagePullSecrets: +######################################################## + +######################################################## +## Exposing service +service: + # type: ClusterIP + type: ClusterIP + annotations: {} + # httpPort: 8080 + # jnlpPort: 50000 + # sshdPort: 16022 + # loadBalancerSourceRanges: 0.0.0.0/0 + # loadBalancerIP: +######################################################## + +######################################################## +## Exposing ingress +## +## Set the jenkinsURL configuration. +## If not set and ingress is enabled, then jenkins URL is +## {{ .Values.ingress.httpProtocol }}://{{ .Values.ingress.hostname }}{{ .Values.ingress.path }} +# jenkinsURL: https://jenkins.host.name +ingress: + ## Change to https if the ingress uses tls or you are using external + ## tls termination using annotations + httpProtocol: http + enabled: true + path: / + pathType: Prefix + ingressClassName: "nginx" + hostname: jenkins.172-18-0-241.nip.io + # annotations: {} + # labels: {} + # tls: + # secretName: + # certificate: + # privateKey: + + ## Ability to add more ingress rules + additionalRules: + # - http: + # paths: + # - path: path + # backend: + preAdditionalRules: +######################################################## + +######################################################## +## By default rbac are not used and default service account +## is being used. +rbac: + ## Create serviceAccount, Eole and RoleBindings + create: true + ## If createServiceAccount = false, and rbac.create = true, the chart will only use the rbac.serviceAaccountName within RoleBindings + createServiceAccount: true + ## Ignored if createServiceAccount = true + serviceAaccountName: "default" + serviceAccount: + annotations: {} + ## Instead of Role, create a ClusterRole and ClusterRoleBindings + clusterWideAccess: false +######################################################## + +######################################################## +## Control requests limit +## It is highly recommended to give jenkins the amount of +## cpu and memory in production usage +resources: +# requests: +# cpu: 200m +# memory: 256Mi +# limits: +# cpu: 200m +# memory: 256Mi +######################################################## + +######################################################## +## It can take a lot of time for jenkins to be started +## This is why the livenessProbe.initialDelaySeconds is high +readinessProbe: + timeoutSeconds: 5 + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 3 + +livenessProbe: + timeoutSeconds: 5 + initialDelaySeconds: 600 + periodSeconds: 5 + failureThreshold: 3 +######################################################## + +######################################################## +## Control peristence of jenkins data: +## By default, the master workspace and master home are separated +## Since master should be used as executer, the workspace directory is +## mainly used for fetching pipeline libraries and some initial clone of +## projects. Therefore, the jenkinsWorkspace can be left as emptyDir (enabled=false). +## On the other hand, jenkinsHome must be persistent! +persistence: + mountDockerSocket: true + jenkinsHome: + enabled: true + annotations: {} + accessMode: ReadWriteOnce + size: 20Gi + ## A manually managed Persistent Volume and Claim + ## Requires persistence.jenkinsHome.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: + ## If defined, storageClass: + ## If set to "-", storageClass: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClass spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "local-path" + jenkinsWorkspace: + enabled: false + annotations: {} + accessMode: ReadWriteOnce + size: 8Gi + ## A manually managed Persistent Volume and Claim + ## Requires persistence.jenkinsWorkspace.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: + ## If defined, storageClass: + ## If set to "-", storageClass: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClass spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "local-path" + + ## Additional volumes and mounts that will be attached to the container. e.g. secrets + volumes: + # - name: nothing + # emptyDir: {} + mounts: + # - mountPath: /var/nothing + # name: nothing + # readOnly: true +######################################################## + +######################################################## +## See: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} +tolerations: [] +affinity: {} +######################################################## + +######################################################## +## Add more annotations to pod +podAnnotations: {} +######################################################## + +######################################################## +## Security Context for jenkins pod +securityContext: {} +######################################################## + +######################################################## +## If true, will set the jenkins master to use hostNetwork=true +useHostNetwork: false +######################################################## + +######################################################## +## Additional Environment variables to be provided to the container +env: +# ENVIRONMENT_VARIABLE_NAME: VALUE +######################################################## + +######################################################## +## If specified, an internal secret will be created. +## Each key will become JENKINS_SECRET_ environment variable +secrets: +# MY_PASSWORD: Very Secret +######################################################## + +######################################################## +## Use external secrets as environment variables +## Each item in the list represents an existing secret name +## All its keys will be transformed to environment variables +## See https://github.com/odavid/my-bloody-jenkins/pull/102 +envSecrets: +# - my-jenkins-external-secret +######################################################## + +######################################################## +## List of ConfigMaps that will be mounted as configuration files +## All configuration files will be deep merged into single config +## See https://github.com/odavid/my-bloody-jenkins/pull/102 +configMaps: +# - my-config-map +######################################################## + +######################################################## +## The jenkins Admin Username - must be a valid username +## within the Jenkins Security Realm +jenkinsAdminUser: admin +######################################################## + +######################################################## +## Java Options for Jenkins Master. Make sure +## resource limits and requests are defined accordingly +javaMemoryOpts: "-Xmx256m" +######################################################## + +######################################################## +## If enabled = 'true', then +## a Default k8s Jenkins cloud will be configured to +## provision slaves automatically based on labels +defaultK8sCloud: + enabled: true + name: "k8s" + labels: + - "generic" + jvmArgs: "-Xmx1g" + remoteFs: "/home/jenkins" + image: "odavid/jenkins-jnlp-slave:latest" +######################################################## + +######################################################## +## A managed configuration based on +## My Bloody Jenkins YAML config. +## See: https://github.com/odavid/my-bloody-jenkins#configuration-reference +managedConfig: {} +## Configure Security - https://github.com/odavid/my-bloody-jenkins#security-section +# security: +## Configure tools - https://github.com/odavid/my-bloody-jenkins#tools-section +# tools: +## Configure credentials - https://github.com/odavid/my-bloody-jenkins#credentials-section +# credentials: +## Configure notifiers - https://github.com/odavid/my-bloody-jenkins#notifiers-section +# notifiers: +## Configure notifiers - https://github.com/odavid/my-bloody-jenkins#pipeline-libraries-section +# pipeline_libraries: +## Script Approvals - https://github.com/odavid/my-bloody-jenkins#script-approval-section +# script_approval: +## Configure Clouds - https://github.com/odavid/my-bloody-jenkins#clouds-section +# clouds: +## Configure Seed Jobs - https://github.com/odavid/my-bloody-jenkins#seed-jobs-section +# seed_jobs: +## Configure Job DSL Scripts - https://github.com/odavid/my-bloody-jenkins#jobdsl-scripts-section +# job_dsl_scripts: +######################################################## From 928ff1d1eb29ff9b22bfa79a09abe590a06c5fc9 Mon Sep 17 00:00:00 2001 From: Marat Date: Sun, 19 Jun 2022 14:39:37 +0400 Subject: [PATCH 12/17] qwe --- apps/templates/my-bloody-jenkins.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 apps/templates/my-bloody-jenkins.yaml diff --git a/apps/templates/my-bloody-jenkins.yaml b/apps/templates/my-bloody-jenkins.yaml new file mode 100644 index 0000000..dc473b6 --- /dev/null +++ b/apps/templates/my-bloody-jenkins.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: my-bloody-jenkins + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: my-bloody-jenkins + server: {{ .Values.spec.destination.server }} + project: default + source: + path: my-bloody-jenkins + repoURL: {{ .Values.spec.source.repoURL }} + targetRevision: {{ .Values.spec.source.targetRevision }} From ff81e959c4cb0f6b929aa661d81126e808e7ba49 Mon Sep 17 00:00:00 2001 From: Marat Date: Sun, 19 Jun 2022 15:02:04 +0400 Subject: [PATCH 13/17] asd --- my-bloody-jenkins/values.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/my-bloody-jenkins/values.yaml b/my-bloody-jenkins/values.yaml index 3d7252a..48fbc67 100644 --- a/my-bloody-jenkins/values.yaml +++ b/my-bloody-jenkins/values.yaml @@ -74,12 +74,12 @@ rbac: ## It is highly recommended to give jenkins the amount of ## cpu and memory in production usage resources: -# requests: -# cpu: 200m -# memory: 256Mi -# limits: -# cpu: 200m -# memory: 256Mi + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: 2000m + memory: 2048Mi ######################################################## ######################################################## @@ -87,7 +87,7 @@ resources: ## This is why the livenessProbe.initialDelaySeconds is high readinessProbe: timeoutSeconds: 5 - initialDelaySeconds: 5 + initialDelaySeconds: 120 periodSeconds: 5 failureThreshold: 3 From 4dad790fa5c472c15dd269a5467daac67d43e463 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 24 Jun 2022 13:29:31 +0400 Subject: [PATCH 14/17] qwe --- nginx-ingress/values.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/nginx-ingress/values.yaml b/nginx-ingress/values.yaml index 695f23b..6a69a77 100644 --- a/nginx-ingress/values.yaml +++ b/nginx-ingress/values.yaml @@ -164,6 +164,7 @@ controller: configMapNamespace: "" # -- Annotations to be added to the tcp config configmap annotations: {} + "22": default/gitea-ssh:22 udp: # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) From 5c179f5c8c4124d701c248232935086209582262 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 24 Jun 2022 13:34:37 +0400 Subject: [PATCH 15/17] qwe --- nginx-ingress/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-ingress/values.yaml b/nginx-ingress/values.yaml index 6a69a77..042c8b4 100644 --- a/nginx-ingress/values.yaml +++ b/nginx-ingress/values.yaml @@ -164,7 +164,7 @@ controller: configMapNamespace: "" # -- Annotations to be added to the tcp config configmap annotations: {} - "22": default/gitea-ssh:22 + "22": "default/gitea-ssh:22" udp: # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) From f11ca209e7641a45c9d9a9dae2258f8d23d8b1b3 Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 24 Jun 2022 13:40:11 +0400 Subject: [PATCH 16/17] qwe --- nginx-ingress/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-ingress/values.yaml b/nginx-ingress/values.yaml index 042c8b4..97f0cea 100644 --- a/nginx-ingress/values.yaml +++ b/nginx-ingress/values.yaml @@ -164,7 +164,7 @@ controller: configMapNamespace: "" # -- Annotations to be added to the tcp config configmap annotations: {} - "22": "default/gitea-ssh:22" + 22: "default/gitea-ssh:22" udp: # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) From 5c211a1474b0e996aa9fb0507513456ead1fc57d Mon Sep 17 00:00:00 2001 From: Marat Date: Fri, 24 Jun 2022 17:43:04 +0400 Subject: [PATCH 17/17] qwe --- nginx-ingress/values.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nginx-ingress/values.yaml b/nginx-ingress/values.yaml index 97f0cea..c647d6c 100644 --- a/nginx-ingress/values.yaml +++ b/nginx-ingress/values.yaml @@ -164,7 +164,6 @@ controller: configMapNamespace: "" # -- Annotations to be added to the tcp config configmap annotations: {} - 22: "default/gitea-ssh:22" udp: # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) @@ -913,7 +912,7 @@ imagePullSecrets: [] # -- TCP service key-value pairs ## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md ## -tcp: {} +tcp: {22: "default/gitea-ssh:22"} # 8080: "default/example-tcp-svc:9000" # -- UDP service key-value pairs