From ef0d2cbceec8c7b62388718c4f5f6cacc9275503 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Aug 2018 22:08:03 -0700 Subject: [PATCH 001/739] Initial commit --- .gitignore | 5 + README.md | 34 +++++ charts/consul/Chart.yaml | 8 ++ charts/consul/templates/_helpers.tpl | 26 ++++ charts/consul/templates/client-daemonset.yaml | 85 ++++++++++++ .../templates/connect-inject-deployment.yaml | 69 ++++++++++ .../connect-inject-mutatingwebhook.yaml | 26 ++++ .../templates/connect-inject-service.yaml | 16 +++ .../templates/server-config-configmap.yaml | 10 ++ .../templates/server-disruptionbudget.yaml | 13 ++ charts/consul/templates/server-service.yaml | 51 +++++++ .../consul/templates/server-statefulset.yaml | 126 ++++++++++++++++++ .../consul/templates/tests/test-config.yaml | 9 ++ .../consul/templates/tests/test-runner.yaml | 37 +++++ charts/consul/templates/ui-service.yaml | 23 ++++ charts/consul/test/_helpers.bash | 45 +++++++ charts/consul/test/server.bats | 17 +++ terraform/README.md | 23 ++++ terraform/main.tf | 9 ++ terraform/modules/README.md | 9 ++ terraform/modules/gke/README.md | 22 +++ terraform/modules/gke/main.tf | 39 ++++++ terraform/modules/gke/outputs.tf | 4 + terraform/modules/gke/variables.tf | 16 +++ terraform/modules/helm/main.tf | 16 +++ terraform/modules/helm/service-account.yaml | 18 +++ terraform/modules/helm/variables.tf | 3 + terraform/variables.tf | 6 + 28 files changed, 765 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 charts/consul/Chart.yaml create mode 100644 charts/consul/templates/_helpers.tpl create mode 100644 charts/consul/templates/client-daemonset.yaml create mode 100644 charts/consul/templates/connect-inject-deployment.yaml create mode 100644 charts/consul/templates/connect-inject-mutatingwebhook.yaml create mode 100644 charts/consul/templates/connect-inject-service.yaml create mode 100644 charts/consul/templates/server-config-configmap.yaml create mode 100644 charts/consul/templates/server-disruptionbudget.yaml create mode 100644 charts/consul/templates/server-service.yaml create mode 100644 charts/consul/templates/server-statefulset.yaml create mode 100644 charts/consul/templates/tests/test-config.yaml create mode 100644 charts/consul/templates/tests/test-runner.yaml create mode 100644 charts/consul/templates/ui-service.yaml create mode 100644 charts/consul/test/_helpers.bash create mode 100644 charts/consul/test/server.bats create mode 100644 terraform/README.md create mode 100644 terraform/main.tf create mode 100644 terraform/modules/README.md create mode 100644 terraform/modules/gke/README.md create mode 100644 terraform/modules/gke/main.tf create mode 100644 terraform/modules/gke/outputs.tf create mode 100644 terraform/modules/gke/variables.tf create mode 100644 terraform/modules/helm/main.tf create mode 100644 terraform/modules/helm/service-account.yaml create mode 100644 terraform/modules/helm/variables.tf create mode 100644 terraform/variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..79f6cb2667 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.terraform/ +terraform.tfstate* +terraform.tfvars +values.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000000..e87106bdd3 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Consul Helm Chart + +This repository contains the official HashiCorp Helm chart for installing +and configuring Consul on Kubernetes. This chart supports multiple use +cases of Consul on Kubernetes depending on the values provided. + +## Prerequisites + +To use the charts here, [Helm](https://helm.sh/) must be installed in your +Kubernetes cluster. Setting up Kubernetes and Helm and is outside the scope +of this README. Please refer to the Kubernetes and Helm documentation. + +## Testing + +The Helm charts are tested in two forms: [Bats](https://github.com/bats-core/bats-core) +tests and `helm test` tests. The Bats tests test changing Helm chart values and +the effect on the install. The `helm test` tests verify that a deployed chart +appears healthy. + +To run the Bats test: `kubectl` must be configured locally to be authenticated +to a running Kubernetes cluster with Helm installed. With that in place, +just run bats: + + bats ./charts/consul/test + +If the tests fail, deployed resources in the Kubernetes cluster may not +be properly cleaned up. We recommend recycling the Kubernetes cluster to +start from a clean slate. + +**Note:** There is a Terraform configuration in the +[terraform/ directory](https://github.com/hashicorp/consul-k8s/tree/master/terraform) +that can be used to quickly bring up a GKE cluster and configure +`kubectl` and `helm` locally. This can be used to quickly spin up a test +cluster. diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml new file mode 100644 index 0000000000..15fefee5b1 --- /dev/null +++ b/charts/consul/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +name: consul +version: 0.1.0 +description: Install and configure Consul on Kubernetes. +home: https://www.consul.io +sources: + - https://github.com/hashicorp/consul + - https://github.com/hashicorp/consul-k8s diff --git a/charts/consul/templates/_helpers.tpl b/charts/consul/templates/_helpers.tpl new file mode 100644 index 0000000000..5126558528 --- /dev/null +++ b/charts/consul/templates/_helpers.tpl @@ -0,0 +1,26 @@ +{{/* +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 "consul.namePrefix" -}} +{{- $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 -}} + +{{/* +Compute the maximum number of unavailable replicas for the PodDisruptionBudget. +This defaults to (n/2)-1 where n is the number of members of the server cluster. +*/}} +{{- define "consul.pdb.maxUnavailable" -}} +{{- if .Values.server.disruptionBudget.maxUnavailable -}} +{{ .Values.server.disruptionBudget.maxUnavailable -}} +{{- else -}} +{{- ceil (sub (div (int .Values.server.replicas) 2) 1) -}} +{{- end -}} +{{- end -}} diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml new file mode 100644 index 0000000000..100528452a --- /dev/null +++ b/charts/consul/templates/client-daemonset.yaml @@ -0,0 +1,85 @@ +# DaemonSet to run the Consul clients on every node. +{{- if .Values.client.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: consul +spec: + selector: + matchLabels: + app: consul + template: + metadata: + labels: + app: consul + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + terminationGracePeriodSeconds: 10 + + # Consul agents require a directory for data, even clients. The data + # is okay to be wiped though if the Pod is removed, so just use an + # emptyDir volume. + volumes: + - name: data + emptyDir: {} + + containers: + - name: consul + image: "{{ .Values.client.image }}" + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + exec /bin/consul agent \ + -advertise="${POD_IP}" \ + -bind=0.0.0.0 \ + -client=0.0.0.0 \ + -datacenter={{ .Values.server.datacenter }} \ + -data-dir=/consul/data \ + {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} + {{- range $value := .Values.client.join }} + -retry-join={{ $value }} \ + {{- end }} + {{- else }} + {{- if .Values.server.enabled }} + {{- range $index := until (.Values.server.replicas | int) }} + -retry-join=consul-server-{{ $index }}.consul-server.${NAMESPACE}.svc \ + {{- end }} + {{- end }} + {{- end }} + -domain={{ .Values.common.domain }} + volumeMounts: + - name: data + mountPath: /consul/data + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - consul leave + ports: + - containerPort: 8500 + hostPort: 8500 + name: http + - containerPort: 8301 + name: serflan + - containerPort: 8302 + name: serfwan + - containerPort: 8300 + name: server + - containerPort: 8600 + name: dns + resources: +{{ toYaml .Values.server.resources | indent 12 }} +{{- end }} diff --git a/charts/consul/templates/connect-inject-deployment.yaml b/charts/consul/templates/connect-inject-deployment.yaml new file mode 100644 index 0000000000..2d9ccce627 --- /dev/null +++ b/charts/consul/templates/connect-inject-deployment.yaml @@ -0,0 +1,69 @@ +# The deployment for running the Connect sidecar injector +{{- if .Values.connectInject.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: consul-connect-injector-webhook-deployment + labels: + app: consul-connect-injector +spec: + replicas: 1 + selector: + matchLabels: + app: consul-connect-injector + template: + metadata: + labels: + app: consul-connect-injector + spec: + containers: + - name: sidecar-injector + image: us.gcr.io/mitchellh-k8s/consul-k8s:latest + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s inject \ + -default-inject={{ .Values.connectInject.default }} \ + -listen=:8080 \ +{{- if .Values.connectInject.certs.secretName }} + -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} + -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} +{{- else }} + -tls-auto=consul-connect-injector-cfg \ + -tls-auto-hosts=consul-connect-injector-svc,consul-connect-injector-svc.${NAMESPACE},consul-connect-injector-svc.${NAMESPACE}.svc +{{- end }} + livenessProbe: + tcpSocket: + port: 8080 + failureThreshold: 2 + initialDelaySeconds: 1 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTPS + failureThreshold: 2 + initialDelaySeconds: 2 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 5 +{{- if .Values.connectInject.certs.secretName }} + volumeMounts: + - name: certs + mountPath: /etc/connect-injector/certs + readOnly: true + volumes: + - name: certs + secret: + secretName: {{ .Values.connectInject.certs.secretName }} +{{- end }} +{{- end }} diff --git a/charts/consul/templates/connect-inject-mutatingwebhook.yaml b/charts/consul/templates/connect-inject-mutatingwebhook.yaml new file mode 100644 index 0000000000..c49d3f0143 --- /dev/null +++ b/charts/consul/templates/connect-inject-mutatingwebhook.yaml @@ -0,0 +1,26 @@ +# The MutatingWebhookConfiguration to enable the Connect injector. +{{- if (.Values.connectInject.enabled) and (.Values.connectInject.caBundle) }} +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: MutatingWebhookConfiguration +metadata: + name: consul-connect-injector-cfg + labels: + app: consul-connect-injector +webhooks: + - name: consul-connect-injector.consul.hashicorp.com + clientConfig: + service: + name: consul-connect-injector-svc + namespace: default + path: "/mutate" + caBundle: {{ .Values.connectInject.caBundle }} + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] +{{- if .Values.connectInject.namespaceSelector }} + namespaceSelector: +{{ tpl .Values.connectInject.namespaceSelector . | indent 6 }} +{{- end }} +{{- end }} diff --git a/charts/consul/templates/connect-inject-service.yaml b/charts/consul/templates/connect-inject-service.yaml new file mode 100644 index 0000000000..cafe095d51 --- /dev/null +++ b/charts/consul/templates/connect-inject-service.yaml @@ -0,0 +1,16 @@ +# The service for the Connect sidecar injector +{{- if .Values.connectInject.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: consul-connect-injector-svc + labels: + app: consul-connect-injector +spec: + ports: + - port: 443 + targetPort: 8080 + selector: + app: consul-connect-injector +{{- end }} + diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml new file mode 100644 index 0000000000..ef44d80826 --- /dev/null +++ b/charts/consul/templates/server-config-configmap.yaml @@ -0,0 +1,10 @@ +# StatefulSet to run the actual Consul server cluster. +{{- if .Values.server.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: consul-server-config +data: + extra-from-values.json: |- +{{ tpl .Values.server.extraConfig . | indent 4 }} +{{- end }} diff --git a/charts/consul/templates/server-disruptionbudget.yaml b/charts/consul/templates/server-disruptionbudget.yaml new file mode 100644 index 0000000000..247d791091 --- /dev/null +++ b/charts/consul/templates/server-disruptionbudget.yaml @@ -0,0 +1,13 @@ +# PodDisruptionBudget to prevent degrading the server cluster through +# voluntary cluster changes. +{{- if (.Values.server.enabled) and (.Values.server.disruptionBudget.enabled) }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: consul-pdb +spec: + maxUnavailable: {{ template "consul.pdb.maxUnavailable" . }} + selector: + matchLabels: + app: consul-server +{{- end }} diff --git a/charts/consul/templates/server-service.yaml b/charts/consul/templates/server-service.yaml new file mode 100644 index 0000000000..78b30ced83 --- /dev/null +++ b/charts/consul/templates/server-service.yaml @@ -0,0 +1,51 @@ +# Headless service for Consul server DNS entries. This service should only +# point to Consul servers. For access to an agent, one should assume that +# the agent is installed locally on the node and the NODE_IP should be used. +# If the node can't run a Consul agent, then this service can be used to +# communicate directly to a server agent. +{{- if .Values.server.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: consul-server + labels: + name: consul-server + annotations: + # This must be set in addition to publishNotReadyAddresses due + # to an open issue where it may not work: + # https://github.com/kubernetes/kubernetes/issues/58662 + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +spec: + clusterIP: None + # We want the servers to become available even if they're not ready + # since this DNS is also used for join operations. + publishNotReadyAddresses: true + ports: + - name: http + port: 8500 + targetPort: 8500 + - name: serflan-tcp + protocol: "TCP" + port: 8301 + targetPort: 8301 + - name: serflan-udp + protocol: "UDP" + port: 8301 + targetPort: 8301 + - name: serfwan-tcp + protocol: "TCP" + port: 8302 + targetPort: 8302 + - name: serfwan-udp + protocol: "UDP" + port: 8302 + targetPort: 8302 + - name: server + port: 8300 + targetPort: 8300 + - name: dns + port: 8600 + targetPort: 8600 + selector: + app: consul-server +{{- end }} diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml new file mode 100644 index 0000000000..e7df2aa94a --- /dev/null +++ b/charts/consul/templates/server-statefulset.yaml @@ -0,0 +1,126 @@ +# StatefulSet to run the actual Consul server cluster. +{{- if .Values.server.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: consul-server +spec: + selector: + matchLabels: + app: consul-server + serviceName: consul-server + podManagementPolicy: Parallel + replicas: {{ .Values.server.replicas }} + {{- if (gt (int .Values.server.updatePartition) 0) }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: {{ .Values.server.updatePartition }} + {{- end }} + template: + metadata: + labels: + app: consul-server + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - consul-server + topologyKey: kubernetes.io/hostname + terminationGracePeriodSeconds: 10 + securityContext: + fsGroup: 1000 + volumes: + - name: config + configMap: + name: consul-server-config + containers: + - name: consul + image: "{{ .Values.server.image }}" + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + exec /bin/consul agent \ + -advertise="${POD_IP}" \ + -bind=0.0.0.0 \ + -bootstrap-expect={{ .Values.server.bootstrapExpect }} \ + -client=0.0.0.0 \ + -config-dir=/consul/config \ + -datacenter={{ .Values.server.datacenter }} \ + -data-dir=/consul/data \ + -domain={{ .Values.common.domain }} \ + {{- if .Values.server.connect }} + -hcl="connect { enabled = true }" \ + {{- end }} + {{- if .Values.ui.enabled }} + -ui \ + {{- end }} + {{- range $index := until (.Values.server.replicas | int) }} + -retry-join=consul-server-{{ $index }}.consul-server.${NAMESPACE}.svc \ + {{- end }} + -server + volumeMounts: + - name: data + mountPath: /consul/data + - name: config + mountPath: /consul/config + lifecycle: + preStop: + exec: + command: + - /bin/sh + - -c + - consul leave + ports: + - containerPort: 8500 + name: http + - containerPort: 8301 + name: serflan + - containerPort: 8302 + name: serfwan + - containerPort: 8300 + name: server + - containerPort: 8600 + name: dns + readinessProbe: + # NOTE(mitchellh): when our HTTP status endpoints support the + # proper status codes, we should switch to that. This is temporary. + exec: + command: + - "/bin/sh" + - "-ec" + - | + curl http://127.0.0.1:8500/v1/status/leader 2>/dev/null | \ + grep -E '".+"' + failureThreshold: 2 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + timeoutSeconds: 5 + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.server.storage }} +{{- end }} diff --git a/charts/consul/templates/tests/test-config.yaml b/charts/consul/templates/tests/test-config.yaml new file mode 100644 index 0000000000..ddfe6f6f90 --- /dev/null +++ b/charts/consul/templates/tests/test-config.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.namePrefix" . }}-tests +data: + run.sh: |- + @test "Testing Consul cluster has quorum" { + [ `kubectl exec {{ template "consul.namePrefix" . }}-server-0 consul members --namespace={{ .Release.Namespace }} | grep server | wc -l` -ge "3" ] + } diff --git a/charts/consul/templates/tests/test-runner.yaml b/charts/consul/templates/tests/test-runner.yaml new file mode 100644 index 0000000000..270a99303c --- /dev/null +++ b/charts/consul/templates/tests/test-runner.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-test-{{ randAlphaNum 5 | lower }}" + annotations: + "helm.sh/hook": test-success +spec: + initContainers: + - name: test-framework + image: dduportal/bats:0.4.0 + command: + - "bash" + - "-c" + - | + set -ex + # copy bats to tools dir + cp -R /usr/local/libexec/ /tools/bats/ + volumeMounts: + - mountPath: /tools + name: tools + containers: + - name: {{ .Release.Name }}-test + image: {{ .Values.test.image }}:{{ .Values.test.imageTag }} + command: ["/tools/bats/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + - mountPath: /tools + name: tools + volumes: + - name: tests + configMap: + name: {{ template "consul.namePrefix" . }}-tests + - name: tools + emptyDir: {} + restartPolicy: Never diff --git a/charts/consul/templates/ui-service.yaml b/charts/consul/templates/ui-service.yaml new file mode 100644 index 0000000000..26da9f6c44 --- /dev/null +++ b/charts/consul/templates/ui-service.yaml @@ -0,0 +1,23 @@ +# Headless service for Consul server DNS entries. This service should only +# point to Consul servers. For access to an agent, one should assume that +# the agent is installed locally on the node and the NODE_IP should be used. +# If the node can't run a Consul agent, then this service can be used to +# communicate directly to a server agent. +{{- if (.Values.server.enabled) and (.Values.ui.enabled) and (.Values.ui.service) }} +apiVersion: v1 +kind: Service +metadata: + name: consul-ui + labels: + name: consul-ui +spec: + selector: + app: consul-server + ports: + - name: http + port: 80 + targetPort: 8500 + {{- if .Values.ui.serviceType }} + type: {{ .Values.ui.serviceType }} + {{- end }} +{{- end }} diff --git a/charts/consul/test/_helpers.bash b/charts/consul/test/_helpers.bash new file mode 100644 index 0000000000..521a10a124 --- /dev/null +++ b/charts/consul/test/_helpers.bash @@ -0,0 +1,45 @@ +# name_prefix returns the prefix of the resources within Kubernetes. +name_prefix() { + printf "consul" +} + +# helm_install installs the Consul chart. +helm_install() { + helm install --name consul --wait ${BATS_TEST_DIRNAME}/.. +} + +# helm_delete deletes the Consul chart and all resources. +helm_delete() { + helm delete --purge consul + kubectl delete --all pvc +} + +# wait for a pod to be ready +wait_for_ready() { + POD_NAME=$1 + + check() { + # This requests the pod and checks whether the status is running + # and the ready state is true. If so, it outputs the name. Otherwise + # it outputs empty. Therefore, to check for success, check for nonzero + # string length. + kubectl get pods $1 -o json | \ + jq -r 'select( + .status.phase == "Running" and + ([ .status.conditions[] | select(.type == "Ready" and .status == "True") ] | length) == 1 + ) | .metadata.namespace + "/" + .metadata.name' + } + + for i in $(seq 30); do + if [ -n "$(check ${POD_NAME})" ]; then + echo "${POD_NAME} is ready." + return + fi + + echo "Waiting for ${POD_NAME} to be ready..." + sleep 2 + done + + echo "${POD_NAME} never became ready." + exit 1 +} diff --git a/charts/consul/test/server.bats b/charts/consul/test/server.bats new file mode 100644 index 0000000000..dc358f6303 --- /dev/null +++ b/charts/consul/test/server.bats @@ -0,0 +1,17 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server: default, comes up healthy" { + helm_install + wait_for_ready $(name_prefix)-server-0 + + # Verify there are three servers + local server_count=$(kubectl exec "$(name_prefix)-server-0" consul members | + grep server | + wc -l) + [ "${server_count}" -eq "3" ] + + # Clean up + helm_delete +} diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000000..8e72a9f518 --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,23 @@ +# Terraform + +This folder contains a Terraform configuration that can be used to setup +an example cluster. These are not meant to be production ready modules for +using Consul with Kubernetes. + +The pre-requisites for Terraform are: + + * Google Cloud authentication. See [Google Application Default Credentials](https://cloud.google.com/docs/authentication/production). You may also reuse your `gcloud` credentials by exposing them as application defaults by running `gcloud auth application-default login`. + * `gcloud` installed and configured locally with GKE components. + * The following programs available on the PATH: `kubectl`, `helm`, `grep`, `xargs`. + +With that available, run the following: + +``` +$ terraform init +$ terraform apply +``` + +The apply will ask you for the name of the project to setup the cluster. +After this, everything will be setup, your local `kubectl` credentials will +be configured, and you may use `helm` directly. + diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000000..f68f9ab788 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,9 @@ +module "gke" { + source = "./modules/gke" + project = "${var.project}" +} + +module "helm" { + source = "./modules/helm" + trigger = "${module.gke.cluster_id}" +} diff --git a/terraform/modules/README.md b/terraform/modules/README.md new file mode 100644 index 0000000000..adcc229ef4 --- /dev/null +++ b/terraform/modules/README.md @@ -0,0 +1,9 @@ +# Terraform Modules + +This directory contains reusable [Terraform](https://www.terraform.io) modules +for various tasks related to Consul and Kubernetes, from spinning up a demo +cluster to running tests. + +These modules are used by our own automated systems for verifying the +functionality of the Consul and Kubernetes components. These modules aren't +meant to be production-ready deployment modules. diff --git a/terraform/modules/gke/README.md b/terraform/modules/gke/README.md new file mode 100644 index 0000000000..d317e64a58 --- /dev/null +++ b/terraform/modules/gke/README.md @@ -0,0 +1,22 @@ +# GKE Cluster Setup + +This module creates a GKE cluster for running and testing the Consul and +Kubernetes integrations. The GKE cluster is an opinionated setup and this +module is not meant to be a generic GKE module. This module also configures +`kubectl` credentials. + +After this module completes, a GKE cluster is created and `kubectl` is +configured such that you can immediately verify the Kubernetes cluster: + + kubectl get componentstatus + +**WARNING:** This module will create resources that cost money. This does +not use free tier resources. + +## Requirements + + * Google Cloud authentication. See [Google Application Default Credentials](https://cloud.google.com/docs/authentication/production). You may also reuse your `gcloud` credentials by exposing them as application defaults by running `gcloud auth application-default login`. + * `gcloud` installed and configured locally with GKE components and available on the PATH. + * `kubectl` installed locally and available on the PATH. + * A Google Cloud Project with GKE and billing activated. + * Unix-like environment that supports piping, `grep`, and `xargs`. diff --git a/terraform/modules/gke/main.tf b/terraform/modules/gke/main.tf new file mode 100644 index 0000000000..3767f4e3db --- /dev/null +++ b/terraform/modules/gke/main.tf @@ -0,0 +1,39 @@ +provider "google" { + project = "${var.project}" +} + +resource "random_id" "suffix" { + byte_length = 4 +} + +resource "google_container_cluster" "cluster" { + name = "consul-k8s-${random_id.suffix.dec}" + project = "${var.project}" + enable_legacy_abac = true + initial_node_count = 5 + zone = "${var.zone}" + min_master_version = "${var.k8s_version}" + node_version = "${var.k8s_version}" +} + +resource "null_resource" "kubectl" { + triggers { + cluster = "${google_container_cluster.cluster.id}" + } + + # On creation, we want to setup the kubectl credentials. The easiest way + # to do this is to shell out to gcloud. + provisioner "local-exec" { + command = "gcloud container clusters get-credentials --zone=${var.zone} ${google_container_cluster.cluster.name}" + } + + # On destroy we want to try to clean up the kubectl credentials. This + # might fail if the credentials are already cleaned up or something so we + # want this to continue on failure. Generally, this works just fine since + # it only operates on local data. + provisioner "local-exec" { + when = "destroy" + on_failure = "continue" + command = "kubectl config get-clusters | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-cluster" + } +} diff --git a/terraform/modules/gke/outputs.tf b/terraform/modules/gke/outputs.tf new file mode 100644 index 0000000000..67e0f1ad8c --- /dev/null +++ b/terraform/modules/gke/outputs.tf @@ -0,0 +1,4 @@ +output "cluster_id" { + value = "${google_container_cluster.cluster.id}" + depends_on = ["null_resource.kubectl"] +} diff --git a/terraform/modules/gke/variables.tf b/terraform/modules/gke/variables.tf new file mode 100644 index 0000000000..d4f6b832f8 --- /dev/null +++ b/terraform/modules/gke/variables.tf @@ -0,0 +1,16 @@ +variable "k8s_version" { + default = "1.10.5-gke.4" + description = "The K8S version to use for both master and nodes." +} + +variable "project" { + description = < Date: Fri, 17 Aug 2018 22:09:05 -0700 Subject: [PATCH 002/739] Add license --- LICENSE.md | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..82b4de97c7 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,353 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. From 8d04c2f6840bb325d764408ffd613818b7b980ff Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Aug 2018 22:27:43 -0700 Subject: [PATCH 003/739] Update README --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index e87106bdd3..09e5d50eb2 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,28 @@ This repository contains the official HashiCorp Helm chart for installing and configuring Consul on Kubernetes. This chart supports multiple use cases of Consul on Kubernetes depending on the values provided. +Please see the [consul-k8s project](https://github.com/hashicorp/consul-k8s) +for the various ways that Consul integrates with Kubernetes. This Helm chart +installs and configures `consul-k8s` in some cases. + ## Prerequisites To use the charts here, [Helm](https://helm.sh/) must be installed in your Kubernetes cluster. Setting up Kubernetes and Helm and is outside the scope of this README. Please refer to the Kubernetes and Helm documentation. +## Usage + +For now, we do not host a Chart repository. To use the charts, you must +download this repository and unpack it into a directory. Then, the chart can +be installed directly: + + helm install ./charts/consul + +Please see the many options supported in the `./charts/consul/values.yaml` +file. These are also fully documented directly on the +[Consul website](https://www.consul.io/docs/). + ## Testing The Helm charts are tested in two forms: [Bats](https://github.com/bats-core/bats-core) From 323feba49c81b27dcf901f38187ffd45d12a6c0e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 18 Aug 2018 14:15:37 -0700 Subject: [PATCH 004/739] Move chart to top-level --- .gitignore | 1 - charts/consul/Chart.yaml => Chart.yaml | 0 README.md | 11 +- .../templates => templates}/_helpers.tpl | 0 .../client-daemonset.yaml | 0 .../connect-inject-deployment.yaml | 0 .../connect-inject-mutatingwebhook.yaml | 0 .../connect-inject-service.yaml | 0 .../server-config-configmap.yaml | 0 .../server-disruptionbudget.yaml | 0 .../server-service.yaml | 0 .../server-statefulset.yaml | 0 .../tests/test-config.yaml | 0 .../tests/test-runner.yaml | 0 .../templates => templates}/ui-service.yaml | 0 {charts/consul/test => test}/_helpers.bash | 0 {charts/consul/test => test}/server.bats | 0 values.yaml | 111 ++++++++++++++++++ 18 files changed, 117 insertions(+), 6 deletions(-) rename charts/consul/Chart.yaml => Chart.yaml (100%) rename {charts/consul/templates => templates}/_helpers.tpl (100%) rename {charts/consul/templates => templates}/client-daemonset.yaml (100%) rename {charts/consul/templates => templates}/connect-inject-deployment.yaml (100%) rename {charts/consul/templates => templates}/connect-inject-mutatingwebhook.yaml (100%) rename {charts/consul/templates => templates}/connect-inject-service.yaml (100%) rename {charts/consul/templates => templates}/server-config-configmap.yaml (100%) rename {charts/consul/templates => templates}/server-disruptionbudget.yaml (100%) rename {charts/consul/templates => templates}/server-service.yaml (100%) rename {charts/consul/templates => templates}/server-statefulset.yaml (100%) rename {charts/consul/templates => templates}/tests/test-config.yaml (100%) rename {charts/consul/templates => templates}/tests/test-runner.yaml (100%) rename {charts/consul/templates => templates}/ui-service.yaml (100%) rename {charts/consul/test => test}/_helpers.bash (100%) rename {charts/consul/test => test}/server.bats (100%) create mode 100644 values.yaml diff --git a/.gitignore b/.gitignore index 79f6cb2667..5ec51a9dd6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ .terraform/ terraform.tfstate* terraform.tfvars -values.yaml diff --git a/charts/consul/Chart.yaml b/Chart.yaml similarity index 100% rename from charts/consul/Chart.yaml rename to Chart.yaml diff --git a/README.md b/README.md index 09e5d50eb2..44757bfbc2 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,13 @@ of this README. Please refer to the Kubernetes and Helm documentation. ## Usage For now, we do not host a Chart repository. To use the charts, you must -download this repository and unpack it into a directory. Then, the chart can -be installed directly: +download this repository and unpack it into a directory. Assuming this +repository was unpacked into the directory `consul-helm`, the chart can +then be installed directly: - helm install ./charts/consul + helm install ./consul-helm -Please see the many options supported in the `./charts/consul/values.yaml` +Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the [Consul website](https://www.consul.io/docs/). @@ -37,7 +38,7 @@ To run the Bats test: `kubectl` must be configured locally to be authenticated to a running Kubernetes cluster with Helm installed. With that in place, just run bats: - bats ./charts/consul/test + bats ./test If the tests fail, deployed resources in the Kubernetes cluster may not be properly cleaned up. We recommend recycling the Kubernetes cluster to diff --git a/charts/consul/templates/_helpers.tpl b/templates/_helpers.tpl similarity index 100% rename from charts/consul/templates/_helpers.tpl rename to templates/_helpers.tpl diff --git a/charts/consul/templates/client-daemonset.yaml b/templates/client-daemonset.yaml similarity index 100% rename from charts/consul/templates/client-daemonset.yaml rename to templates/client-daemonset.yaml diff --git a/charts/consul/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml similarity index 100% rename from charts/consul/templates/connect-inject-deployment.yaml rename to templates/connect-inject-deployment.yaml diff --git a/charts/consul/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml similarity index 100% rename from charts/consul/templates/connect-inject-mutatingwebhook.yaml rename to templates/connect-inject-mutatingwebhook.yaml diff --git a/charts/consul/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml similarity index 100% rename from charts/consul/templates/connect-inject-service.yaml rename to templates/connect-inject-service.yaml diff --git a/charts/consul/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml similarity index 100% rename from charts/consul/templates/server-config-configmap.yaml rename to templates/server-config-configmap.yaml diff --git a/charts/consul/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml similarity index 100% rename from charts/consul/templates/server-disruptionbudget.yaml rename to templates/server-disruptionbudget.yaml diff --git a/charts/consul/templates/server-service.yaml b/templates/server-service.yaml similarity index 100% rename from charts/consul/templates/server-service.yaml rename to templates/server-service.yaml diff --git a/charts/consul/templates/server-statefulset.yaml b/templates/server-statefulset.yaml similarity index 100% rename from charts/consul/templates/server-statefulset.yaml rename to templates/server-statefulset.yaml diff --git a/charts/consul/templates/tests/test-config.yaml b/templates/tests/test-config.yaml similarity index 100% rename from charts/consul/templates/tests/test-config.yaml rename to templates/tests/test-config.yaml diff --git a/charts/consul/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml similarity index 100% rename from charts/consul/templates/tests/test-runner.yaml rename to templates/tests/test-runner.yaml diff --git a/charts/consul/templates/ui-service.yaml b/templates/ui-service.yaml similarity index 100% rename from charts/consul/templates/ui-service.yaml rename to templates/ui-service.yaml diff --git a/charts/consul/test/_helpers.bash b/test/_helpers.bash similarity index 100% rename from charts/consul/test/_helpers.bash rename to test/_helpers.bash diff --git a/charts/consul/test/server.bats b/test/server.bats similarity index 100% rename from charts/consul/test/server.bats rename to test/server.bats diff --git a/values.yaml b/values.yaml new file mode 100644 index 0000000000..e8f316b156 --- /dev/null +++ b/values.yaml @@ -0,0 +1,111 @@ +# Available parameters and their default values for the Consul chart. + +# Server, when enabled, configures a server cluster to run. This should +# be disabled if you plan on connecting to a Consul cluster external to +# the Kube cluster. + +common: + # Domain to register the Consul DNS server to listen for. + domain: consul + +server: + enabled: true + image: "consul:1.2.2" + replicas: 3 + bootstrapExpect: 3 # Should <= replicas count + storage: 10Gi + + # connect will enable Connect on all the servers, initializing a CA + # for Connect-related connections. Other customizations can be done + # via the extraConfig setting. + connect: true + + # Datacenter is the name of the datacenter that the server should register + # as. This shouldn't be changed once the Consul cluster is up and running + # since Consul doesn't support an automatic way to change this value + # currently: https://github.com/hashicorp/consul/issues/1858 + datacenter: dc1 + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + resources: {} + + # updatePartition is used to control a careful rolling update of Consul + # servers. This should be done particularly when changing the version + # of Consul. Please refer to the documentation for more information. + updatePartition: 0 + + # disruptionBudget enables the creation of a PodDisruptionBudget to + # prevent voluntary degrading of the Consul server cluster. + disruptionBudget: + enabled: true + + # maxUnavailable will default to (n/2)-1 where n is the number of + # replicas. If you'd like a custom value, you can specify an override here. + maxUnavailable: null + + # extraConfig is a raw string of extra configuration to set with the + # server. This should be JSON or HCL. + extraConfig: | + {} + +# Client, when enabled, configures Consul clients to run on every node +# within the Kube cluster. The current deployment model follows a traditional +# DC where a single agent is deployed per node. +client: + enabled: true + image: "consul:1.2.2" + join: null + +# ConnectInject will enable the automatic Connect sidecar injector. +connectInject: + enabled: true + default: false # true will inject by default, otherwise requires annotation + caBundle: "" # empty will auto generate the bundle + + # namespaceSelector is the selector for restricting the webhook to only + # specific namespaces. This should be set to a multiline string. + namespaceSelector: null + + # The certs section configures how the webhook TLS certs are configured. + # These are the TLS certs for the Kube apiserver communicating to the + # webhook. By default, the injector will generate and manage its own certs, + # but this requires the ability for the injector to update its own + # MutatingWebhookConfiguration. In a production environment, custom certs + # should probaly be used. Configure the values below to enable this. + certs: + # secretName is the name of the secret that has the TLS certificate and + # private key to serve the injector webhook. If this is null, then the + # injector will default to its automatic management mode. + secretName: null + + # caBundle is a base64-encoded PEM-encoded certificate bundle for the + # CA that signed the TLS certificate that the webhook serves. This must + # be set if secretName is non-null. + caBundle: "" + + # certName and keyName are the names of the files within the secret for + # the TLS cert and private key, respectively. These have reasonable + # defaults but can be customized if necessary. + certName: tls.crt + keyName: tls.key + +ui: + # True if you want to enable the Consul UI. The UI will run only + # on the server nodes. This makes UI access via the service below (if + # enabled) predictable rather than "any node" if you're running Consul + # clients as well. + enabled: true + + # True if you want to create a Service entry for the Consul UI. + # + # serviceType can be used to control the type of service created. For + # example, setting this to "LoadBalancer" will create an external load + # balancer (for supported K8S installations) to access the UI. + service: true + serviceType: null + +test: + image: lachlanevenson/k8s-kubectl + imageTag: v1.4.8-bash From 60e57f700ea50807e86ee58e0707475141156bf8 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 18 Aug 2018 14:38:33 -0700 Subject: [PATCH 005/739] setup templates for proper name prefixing --- .gitignore | 1 + .helmignore | 2 + templates/_helpers.tpl | 20 +++++++++- templates/client-daemonset.yaml | 21 ++++++++-- templates/connect-inject-deployment.yaml | 21 +++++++--- templates/connect-inject-mutatingwebhook.yaml | 11 ++++-- templates/connect-inject-service.yaml | 11 ++++-- templates/server-config-configmap.yaml | 7 +++- templates/server-disruptionbudget.yaml | 11 +++++- templates/server-service.yaml | 11 ++++-- templates/server-statefulset.yaml | 38 ++++++++++++------- templates/tests/test-config.yaml | 4 +- templates/tests/test-runner.yaml | 2 +- templates/ui-service.yaml | 11 ++++-- 14 files changed, 129 insertions(+), 42 deletions(-) create mode 100644 .helmignore diff --git a/.gitignore b/.gitignore index 5ec51a9dd6..7b7c9b118e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .terraform/ terraform.tfstate* terraform.tfvars +values.dev.yaml diff --git a/.helmignore b/.helmignore new file mode 100644 index 0000000000..4f85fe7a9d --- /dev/null +++ b/.helmignore @@ -0,0 +1,2 @@ +.git/ +.terraform/ diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 5126558528..ec9e77359b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -4,7 +4,10 @@ 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 "consul.namePrefix" -}} +{{- define "consul.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 "-" -}} @@ -12,6 +15,21 @@ be used as a full name. {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "consul.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "consul.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} {{/* Compute the maximum number of unavailable replicas for the PodDisruptionBudget. diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 100528452a..c32d48e9d2 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -3,15 +3,26 @@ apiVersion: apps/v1 kind: DaemonSet metadata: - name: consul + name: {{ template "consul.fullname" . }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: selector: matchLabels: - app: consul + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client template: metadata: labels: - app: consul + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client annotations: "consul.hashicorp.com/connect-inject": "false" spec: @@ -40,6 +51,8 @@ spec: - "/bin/sh" - "-ec" - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + exec /bin/consul agent \ -advertise="${POD_IP}" \ -bind=0.0.0.0 \ @@ -53,7 +66,7 @@ spec: {{- else }} {{- if .Values.server.enabled }} {{- range $index := until (.Values.server.replicas | int) }} - -retry-join=consul-server-{{ $index }}.consul-server.${NAMESPACE}.svc \ + -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} {{- end }} {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 2d9ccce627..77491d01c7 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -3,18 +3,27 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: consul-connect-injector-webhook-deployment + name: {{ template "consul.fullname" }}-connect-injector-webhook-deployment labels: - app: consul-connect-injector + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: replicas: 1 selector: matchLabels: - app: consul-connect-injector + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: connect-injector template: metadata: labels: - app: consul-connect-injector + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: connect-injector spec: containers: - name: sidecar-injector @@ -28,6 +37,8 @@ spec: - "/bin/sh" - "-ec" - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + consul-k8s inject \ -default-inject={{ .Values.connectInject.default }} \ -listen=:8080 \ @@ -36,7 +47,7 @@ spec: -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} {{- else }} -tls-auto=consul-connect-injector-cfg \ - -tls-auto-hosts=consul-connect-injector-svc,consul-connect-injector-svc.${NAMESPACE},consul-connect-injector-svc.${NAMESPACE}.svc + -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc {{- end }} livenessProbe: tcpSocket: diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index c49d3f0143..387e4fb910 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -3,14 +3,17 @@ apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: - name: consul-connect-injector-cfg + name: {{ template "consul.fullname" . }}-connect-injector-cfg labels: - app: consul-connect-injector + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} webhooks: - - name: consul-connect-injector.consul.hashicorp.com + - name: {{ template "consul.fullname" . }}-connect-injector.consul.hashicorp.com clientConfig: service: - name: consul-connect-injector-svc + name: {{ template "consul.fullname" . }}-connect-injector-svc namespace: default path: "/mutate" caBundle: {{ .Values.connectInject.caBundle }} diff --git a/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml index cafe095d51..65c2efaeae 100644 --- a/templates/connect-inject-service.yaml +++ b/templates/connect-inject-service.yaml @@ -3,14 +3,19 @@ apiVersion: v1 kind: Service metadata: - name: consul-connect-injector-svc + name: {{ template "consul.fullname" . }}-connect-injector-svc labels: - app: consul-connect-injector + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: ports: - port: 443 targetPort: 8080 selector: - app: consul-connect-injector + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: connect-injector {{- end }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index ef44d80826..7d1c7fd3a2 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -3,7 +3,12 @@ apiVersion: v1 kind: ConfigMap metadata: - name: consul-server-config + name: {{ template "consul.fullname" . }}-server-config + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} data: extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | indent 4 }} diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index 247d791091..f06087af63 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -4,10 +4,17 @@ apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: - name: consul-pdb + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: maxUnavailable: {{ template "consul.pdb.maxUnavailable" . }} selector: matchLabels: - app: consul-server + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server {{- end }} diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 78b30ced83..5e02384738 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -7,9 +7,12 @@ apiVersion: v1 kind: Service metadata: - name: consul-server + name: {{ template "consul.fullname" . }}-server labels: - name: consul-server + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} annotations: # This must be set in addition to publishNotReadyAddresses due # to an open issue where it may not work: @@ -47,5 +50,7 @@ spec: port: 8600 targetPort: 8600 selector: - app: consul-server + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index e7df2aa94a..728e9a914a 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -3,12 +3,14 @@ apiVersion: apps/v1 kind: StatefulSet metadata: - name: consul-server + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: - selector: - matchLabels: - app: consul-server - serviceName: consul-server + serviceName: {{ template "consul.fullname" . }}-server podManagementPolicy: Parallel replicas: {{ .Values.server.replicas }} {{- if (gt (int .Values.server.updatePartition) 0) }} @@ -17,10 +19,19 @@ spec: rollingUpdate: partition: {{ .Values.server.updatePartition }} {{- end }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server template: metadata: labels: - app: consul-server + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server annotations: "consul.hashicorp.com/connect-inject": "false" spec: @@ -28,11 +39,10 @@ spec: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - consul-server + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: 10 securityContext: @@ -40,7 +50,7 @@ spec: volumes: - name: config configMap: - name: consul-server-config + name: {{ template "consul.fullname" . }}-server-config containers: - name: consul image: "{{ .Values.server.image }}" @@ -57,6 +67,8 @@ spec: - "/bin/sh" - "-ec" - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + exec /bin/consul agent \ -advertise="${POD_IP}" \ -bind=0.0.0.0 \ @@ -73,7 +85,7 @@ spec: -ui \ {{- end }} {{- range $index := until (.Values.server.replicas | int) }} - -retry-join=consul-server-{{ $index }}.consul-server.${NAMESPACE}.svc \ + -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} -server volumeMounts: diff --git a/templates/tests/test-config.yaml b/templates/tests/test-config.yaml index ddfe6f6f90..26fef08f25 100644 --- a/templates/tests/test-config.yaml +++ b/templates/tests/test-config.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ template "consul.namePrefix" . }}-tests + name: {{ template "consul.fullname" . }}-tests data: run.sh: |- @test "Testing Consul cluster has quorum" { - [ `kubectl exec {{ template "consul.namePrefix" . }}-server-0 consul members --namespace={{ .Release.Namespace }} | grep server | wc -l` -ge "3" ] + [ `kubectl exec {{ template "consul.fullname" . }}-server-0 consul members --namespace={{ .Release.Namespace }} | grep server | wc -l` -ge "3" ] } diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 270a99303c..65b6b6081a 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -31,7 +31,7 @@ spec: volumes: - name: tests configMap: - name: {{ template "consul.namePrefix" . }}-tests + name: {{ template "consul.fullname" . }}-tests - name: tools emptyDir: {} restartPolicy: Never diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index 26da9f6c44..d2fd328531 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -7,12 +7,17 @@ apiVersion: v1 kind: Service metadata: - name: consul-ui + name: {{ template "consul.fullname" . }}-ui labels: - name: consul-ui + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} spec: selector: - app: consul-server + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server ports: - name: http port: 80 From f2e2bd7a5295cd702d710787019bdce7d87b7a0d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 18 Aug 2018 14:55:33 -0700 Subject: [PATCH 006/739] fix typo that caused connect injector to not work --- templates/connect-inject-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 77491d01c7..c15a5b0c88 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -3,7 +3,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ template "consul.fullname" }}-connect-injector-webhook-deployment + name: {{ template "consul.fullname" . }}-connect-injector-webhook-deployment labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} From b2f7df6d7783675fbc21330712cd9504e4e98e24 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 18 Aug 2018 15:19:09 -0700 Subject: [PATCH 007/739] terraform/gke: clean up kubeconfig better, still not perfect --- terraform/modules/gke/main.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/terraform/modules/gke/main.tf b/terraform/modules/gke/main.tf index 3767f4e3db..6281c82d2c 100644 --- a/terraform/modules/gke/main.tf +++ b/terraform/modules/gke/main.tf @@ -36,4 +36,10 @@ resource "null_resource" "kubectl" { on_failure = "continue" command = "kubectl config get-clusters | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-cluster" } + + provisioner "local-exec" { + when = "destroy" + on_failure = "continue" + command = "kubectl config get-contexts | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-context" + } } From c7fa40d247146ae6f43f072dc45f3bd913b28f9b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 20 Aug 2018 15:26:37 -0700 Subject: [PATCH 008/739] Initial stuff --- Makefile | 6 ++ test/{ => acceptance}/_helpers.bash | 0 test/{ => acceptance}/server.bats | 0 test/docker/Test.dockerfile | 40 +++++++++++++ test/scripts/cli-init.sh | 88 +++++++++++++++++++++++++++++ test/scripts/docker-init.sh | 51 +++++++++++++++++ test/terraform/main.tf | 18 ++++++ test/terraform/variables.tf | 17 ++++++ 8 files changed, 220 insertions(+) create mode 100644 Makefile rename test/{ => acceptance}/_helpers.bash (100%) rename test/{ => acceptance}/server.bats (100%) create mode 100644 test/docker/Test.dockerfile create mode 100755 test/scripts/cli-init.sh create mode 100644 test/scripts/docker-init.sh create mode 100644 test/terraform/main.tf create mode 100644 test/terraform/variables.tf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..ec8cd7505f --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +TEST_IMAGE?=consul-helm-test + +test-docker: + @docker build --rm -t '$(TEST_IMAGE)' -f $(CURDIR)/test/docker/Test.dockerfile $(CURDIR) + +.PHONY: test-docker diff --git a/test/_helpers.bash b/test/acceptance/_helpers.bash similarity index 100% rename from test/_helpers.bash rename to test/acceptance/_helpers.bash diff --git a/test/server.bats b/test/acceptance/server.bats similarity index 100% rename from test/server.bats rename to test/acceptance/server.bats diff --git a/test/docker/Test.dockerfile b/test/docker/Test.dockerfile new file mode 100644 index 0000000000..505ce3e55f --- /dev/null +++ b/test/docker/Test.dockerfile @@ -0,0 +1,40 @@ +# This Dockerfile installs all the dependencies necessary to run the +# acceptance tests. This image also contains gcloud so you can run tests +# against a GKE cluster easily. +# +# This image has no automatic entrypoint. It is expected that you'll run +# a script to configure kubectl, potentially install Helm, and run the tests +# manually. This image only has the dependencies pre-installed. + +FROM alpine:latest +WORKDIR /root + +ENV BATS_VERSION "1.1.0" + +# base packages +RUN apk update && apk add --no-cache --virtual .build-deps \ + ca-certificates \ + curl \ + tar \ + bash \ + openssl \ + python \ + git + +# gcloud +RUN curl -OL https://dl.google.com/dl/cloudsdk/channels/rapid/install_google_cloud_sdk.bash && \ + bash install_google_cloud_sdk.bash --disable-prompts --install-dir='/root/' && \ + ln -s /root/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud + +# kubectl +RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ + chmod +x ./kubectl && \ + mv ./kubectl /usr/local/bin/kubectl + +# helm +RUN curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash + +# bats +RUN curl -sSL https://github.com/bats-core/bats-core/archive/v${BATS_VERSION}.tar.gz -o /tmp/bats.tgz \ + && tar -zxf /tmp/bats.tgz -C /tmp \ + && /bin/bash /tmp/bats-core-$BATS_VERSION/install.sh /usr/local diff --git a/test/scripts/cli-init.sh b/test/scripts/cli-init.sh new file mode 100755 index 0000000000..cd0b70c23f --- /dev/null +++ b/test/scripts/cli-init.sh @@ -0,0 +1,88 @@ +#!/bin/bash +SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null +SCRIPT_DIR=$(pwd) +popd > /dev/null + +function usage { +cat <<-EOF +Usage: ${SCRIPT_NAME} [] +Description: + This script will initialize + This script will build the consul-k8s binary on the local system. + All the requisite tooling must be installed for this to be + successful. +Options: + -s | --source DIR Path to source to build. + Defaults to "${SOURCE_DIR}" + -o | --os OSES Space separated string of OS + platforms to build. + -a | --arch ARCH Space separated string of + architectures to build. + -h | --help Print this help text. +EOF +} + +function main { + declare sdir="${SOURCE_DIR}" + declare build_os="" + declare build_arch="" + + + while test $# -gt 0 + do + case "$1" in + -h | --help ) + usage + return 0 + ;; + -s | --source ) + if test -z "$2" + then + err_usage "ERROR: option -s/--source requires an argument" + return 1 + fi + + if ! test -d "$2" + then + err_usage "ERROR: '$2' is not a directory and not suitable for the value of -s/--source" + return 1 + fi + + sdir="$2" + shift 2 + ;; + -o | --os ) + if test -z "$2" + then + err_usage "ERROR: option -o/--os requires an argument" + return 1 + fi + + build_os="$2" + shift 2 + ;; + -a | --arch ) + if test -z "$2" + then + err_usage "ERROR: option -a/--arch requires an argument" + return 1 + fi + + build_arch="$2" + shift 2 + ;; + * ) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + build_consul_local "${sdir}" "${build_os}" "${build_arch}" || return 1 + + return 0 +} + +main "$@" +exit $? diff --git a/test/scripts/docker-init.sh b/test/scripts/docker-init.sh new file mode 100644 index 0000000000..16f47d710a --- /dev/null +++ b/test/scripts/docker-init.sh @@ -0,0 +1,51 @@ +#!/bin/bash +SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null +SCRIPT_DIR=$(pwd) +popd > /dev/null + +function usage { +cat <<-EOF +Usage: ${SCRIPT_NAME} [] +Description: + This script will install the necessary components for a Docker-based + test. + This script will build the consul-k8s binary on the local system. + All the requisite tooling must be installed for this to be + successful. +Options: + -s | --source DIR Path to source to build. + Defaults to "${SOURCE_DIR}" + -o | --os OSES Space separated string of OS + platforms to build. + -a | --arch ARCH Space separated string of + architectures to build. + -h | --help Print this help text. +EOF +} + +function main { + declare sdir="${SOURCE_DIR}" + declare build_os="" + declare build_arch="" + + while test $# -gt 0 + do + case "$1" in + -h | --help ) + usage + return 0 + ;; + * ) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + build_consul_local "${sdir}" "${build_os}" "${build_arch}" || return 1 + return 0 +} + +main "$@" +exit $? diff --git a/test/terraform/main.tf b/test/terraform/main.tf new file mode 100644 index 0000000000..7564ef3694 --- /dev/null +++ b/test/terraform/main.tf @@ -0,0 +1,18 @@ +provider "google" { + project = "${var.project}" +} + +resource "random_id" "suffix" { + byte_length = 4 +} + +resource "google_container_cluster" "cluster" { + name = "consul-k8s-${random_id.suffix.dec}" + project = "${var.project}" + enable_legacy_abac = true + initial_node_count = 5 + zone = "${var.zone}" + min_master_version = "${var.k8s_version}" + node_version = "${var.k8s_version}" +} + diff --git a/test/terraform/variables.tf b/test/terraform/variables.tf new file mode 100644 index 0000000000..047cb924a6 --- /dev/null +++ b/test/terraform/variables.tf @@ -0,0 +1,17 @@ +variable "k8s_version" { + default = "1.10.5-gke.4" + description = "The K8S version to use for both master and nodes." +} + +variable "project" { + description = < Date: Mon, 20 Aug 2018 15:54:04 -0700 Subject: [PATCH 009/739] test/terraform: add cluster outputs --- test/terraform/outputs.tf | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/terraform/outputs.tf diff --git a/test/terraform/outputs.tf b/test/terraform/outputs.tf new file mode 100644 index 0000000000..6435d2b78f --- /dev/null +++ b/test/terraform/outputs.tf @@ -0,0 +1,7 @@ +output "cluster_id" { + value = "${google_container_cluster.cluster.id}" +} + +output "cluster_name" { + value = "${google_container_cluster.cluster.name}" +} From 36e8afc7a02384595b768a0e4819066a71fe7b1a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 20 Aug 2018 16:15:47 -0700 Subject: [PATCH 010/739] Move all terraform setup to test/terraform --- .gitignore | 1 + README.md | 2 +- terraform/README.md | 23 ----- terraform/main.tf | 9 -- terraform/modules/README.md | 9 -- terraform/modules/gke/README.md | 22 ----- terraform/modules/gke/main.tf | 45 ---------- terraform/modules/gke/outputs.tf | 4 - terraform/modules/gke/variables.tf | 16 ---- terraform/modules/helm/main.tf | 16 ---- terraform/modules/helm/variables.tf | 3 - terraform/variables.tf | 6 -- test/scripts/cli-init.sh | 88 ------------------- test/scripts/docker-init.sh | 51 ----------- test/terraform/main.tf | 48 ++++++++++ .../terraform}/service-account.yaml | 0 test/terraform/variables.tf | 5 ++ 17 files changed, 55 insertions(+), 293 deletions(-) delete mode 100644 terraform/README.md delete mode 100644 terraform/main.tf delete mode 100644 terraform/modules/README.md delete mode 100644 terraform/modules/gke/README.md delete mode 100644 terraform/modules/gke/main.tf delete mode 100644 terraform/modules/gke/outputs.tf delete mode 100644 terraform/modules/gke/variables.tf delete mode 100644 terraform/modules/helm/main.tf delete mode 100644 terraform/modules/helm/variables.tf delete mode 100644 terraform/variables.tf delete mode 100755 test/scripts/cli-init.sh delete mode 100644 test/scripts/docker-init.sh rename {terraform/modules/helm => test/terraform}/service-account.yaml (100%) diff --git a/.gitignore b/.gitignore index 7b7c9b118e..f7de6f7f94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store .terraform/ +.terraform.tfstate* terraform.tfstate* terraform.tfvars values.dev.yaml diff --git a/README.md b/README.md index 44757bfbc2..9cc9e8f566 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ be properly cleaned up. We recommend recycling the Kubernetes cluster to start from a clean slate. **Note:** There is a Terraform configuration in the -[terraform/ directory](https://github.com/hashicorp/consul-k8s/tree/master/terraform) +[test/terraform/ directory](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) that can be used to quickly bring up a GKE cluster and configure `kubectl` and `helm` locally. This can be used to quickly spin up a test cluster. diff --git a/terraform/README.md b/terraform/README.md deleted file mode 100644 index 8e72a9f518..0000000000 --- a/terraform/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Terraform - -This folder contains a Terraform configuration that can be used to setup -an example cluster. These are not meant to be production ready modules for -using Consul with Kubernetes. - -The pre-requisites for Terraform are: - - * Google Cloud authentication. See [Google Application Default Credentials](https://cloud.google.com/docs/authentication/production). You may also reuse your `gcloud` credentials by exposing them as application defaults by running `gcloud auth application-default login`. - * `gcloud` installed and configured locally with GKE components. - * The following programs available on the PATH: `kubectl`, `helm`, `grep`, `xargs`. - -With that available, run the following: - -``` -$ terraform init -$ terraform apply -``` - -The apply will ask you for the name of the project to setup the cluster. -After this, everything will be setup, your local `kubectl` credentials will -be configured, and you may use `helm` directly. - diff --git a/terraform/main.tf b/terraform/main.tf deleted file mode 100644 index f68f9ab788..0000000000 --- a/terraform/main.tf +++ /dev/null @@ -1,9 +0,0 @@ -module "gke" { - source = "./modules/gke" - project = "${var.project}" -} - -module "helm" { - source = "./modules/helm" - trigger = "${module.gke.cluster_id}" -} diff --git a/terraform/modules/README.md b/terraform/modules/README.md deleted file mode 100644 index adcc229ef4..0000000000 --- a/terraform/modules/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Terraform Modules - -This directory contains reusable [Terraform](https://www.terraform.io) modules -for various tasks related to Consul and Kubernetes, from spinning up a demo -cluster to running tests. - -These modules are used by our own automated systems for verifying the -functionality of the Consul and Kubernetes components. These modules aren't -meant to be production-ready deployment modules. diff --git a/terraform/modules/gke/README.md b/terraform/modules/gke/README.md deleted file mode 100644 index d317e64a58..0000000000 --- a/terraform/modules/gke/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# GKE Cluster Setup - -This module creates a GKE cluster for running and testing the Consul and -Kubernetes integrations. The GKE cluster is an opinionated setup and this -module is not meant to be a generic GKE module. This module also configures -`kubectl` credentials. - -After this module completes, a GKE cluster is created and `kubectl` is -configured such that you can immediately verify the Kubernetes cluster: - - kubectl get componentstatus - -**WARNING:** This module will create resources that cost money. This does -not use free tier resources. - -## Requirements - - * Google Cloud authentication. See [Google Application Default Credentials](https://cloud.google.com/docs/authentication/production). You may also reuse your `gcloud` credentials by exposing them as application defaults by running `gcloud auth application-default login`. - * `gcloud` installed and configured locally with GKE components and available on the PATH. - * `kubectl` installed locally and available on the PATH. - * A Google Cloud Project with GKE and billing activated. - * Unix-like environment that supports piping, `grep`, and `xargs`. diff --git a/terraform/modules/gke/main.tf b/terraform/modules/gke/main.tf deleted file mode 100644 index 6281c82d2c..0000000000 --- a/terraform/modules/gke/main.tf +++ /dev/null @@ -1,45 +0,0 @@ -provider "google" { - project = "${var.project}" -} - -resource "random_id" "suffix" { - byte_length = 4 -} - -resource "google_container_cluster" "cluster" { - name = "consul-k8s-${random_id.suffix.dec}" - project = "${var.project}" - enable_legacy_abac = true - initial_node_count = 5 - zone = "${var.zone}" - min_master_version = "${var.k8s_version}" - node_version = "${var.k8s_version}" -} - -resource "null_resource" "kubectl" { - triggers { - cluster = "${google_container_cluster.cluster.id}" - } - - # On creation, we want to setup the kubectl credentials. The easiest way - # to do this is to shell out to gcloud. - provisioner "local-exec" { - command = "gcloud container clusters get-credentials --zone=${var.zone} ${google_container_cluster.cluster.name}" - } - - # On destroy we want to try to clean up the kubectl credentials. This - # might fail if the credentials are already cleaned up or something so we - # want this to continue on failure. Generally, this works just fine since - # it only operates on local data. - provisioner "local-exec" { - when = "destroy" - on_failure = "continue" - command = "kubectl config get-clusters | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-cluster" - } - - provisioner "local-exec" { - when = "destroy" - on_failure = "continue" - command = "kubectl config get-contexts | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-context" - } -} diff --git a/terraform/modules/gke/outputs.tf b/terraform/modules/gke/outputs.tf deleted file mode 100644 index 67e0f1ad8c..0000000000 --- a/terraform/modules/gke/outputs.tf +++ /dev/null @@ -1,4 +0,0 @@ -output "cluster_id" { - value = "${google_container_cluster.cluster.id}" - depends_on = ["null_resource.kubectl"] -} diff --git a/terraform/modules/gke/variables.tf b/terraform/modules/gke/variables.tf deleted file mode 100644 index d4f6b832f8..0000000000 --- a/terraform/modules/gke/variables.tf +++ /dev/null @@ -1,16 +0,0 @@ -variable "k8s_version" { - default = "1.10.5-gke.4" - description = "The K8S version to use for both master and nodes." -} - -variable "project" { - description = < /dev/null -SCRIPT_DIR=$(pwd) -popd > /dev/null - -function usage { -cat <<-EOF -Usage: ${SCRIPT_NAME} [] -Description: - This script will initialize - This script will build the consul-k8s binary on the local system. - All the requisite tooling must be installed for this to be - successful. -Options: - -s | --source DIR Path to source to build. - Defaults to "${SOURCE_DIR}" - -o | --os OSES Space separated string of OS - platforms to build. - -a | --arch ARCH Space separated string of - architectures to build. - -h | --help Print this help text. -EOF -} - -function main { - declare sdir="${SOURCE_DIR}" - declare build_os="" - declare build_arch="" - - - while test $# -gt 0 - do - case "$1" in - -h | --help ) - usage - return 0 - ;; - -s | --source ) - if test -z "$2" - then - err_usage "ERROR: option -s/--source requires an argument" - return 1 - fi - - if ! test -d "$2" - then - err_usage "ERROR: '$2' is not a directory and not suitable for the value of -s/--source" - return 1 - fi - - sdir="$2" - shift 2 - ;; - -o | --os ) - if test -z "$2" - then - err_usage "ERROR: option -o/--os requires an argument" - return 1 - fi - - build_os="$2" - shift 2 - ;; - -a | --arch ) - if test -z "$2" - then - err_usage "ERROR: option -a/--arch requires an argument" - return 1 - fi - - build_arch="$2" - shift 2 - ;; - * ) - err_usage "ERROR: Unknown argument: '$1'" - return 1 - ;; - esac - done - - build_consul_local "${sdir}" "${build_os}" "${build_arch}" || return 1 - - return 0 -} - -main "$@" -exit $? diff --git a/test/scripts/docker-init.sh b/test/scripts/docker-init.sh deleted file mode 100644 index 16f47d710a..0000000000 --- a/test/scripts/docker-init.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" -pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null -SCRIPT_DIR=$(pwd) -popd > /dev/null - -function usage { -cat <<-EOF -Usage: ${SCRIPT_NAME} [] -Description: - This script will install the necessary components for a Docker-based - test. - This script will build the consul-k8s binary on the local system. - All the requisite tooling must be installed for this to be - successful. -Options: - -s | --source DIR Path to source to build. - Defaults to "${SOURCE_DIR}" - -o | --os OSES Space separated string of OS - platforms to build. - -a | --arch ARCH Space separated string of - architectures to build. - -h | --help Print this help text. -EOF -} - -function main { - declare sdir="${SOURCE_DIR}" - declare build_os="" - declare build_arch="" - - while test $# -gt 0 - do - case "$1" in - -h | --help ) - usage - return 0 - ;; - * ) - err_usage "ERROR: Unknown argument: '$1'" - return 1 - ;; - esac - done - - build_consul_local "${sdir}" "${build_os}" "${build_arch}" || return 1 - return 0 -} - -main "$@" -exit $? diff --git a/test/terraform/main.tf b/test/terraform/main.tf index 7564ef3694..64be711bd7 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -1,3 +1,7 @@ +locals { + service_account_path = "${path.module}/service-account.yaml" +} + provider "google" { project = "${var.project}" } @@ -16,3 +20,47 @@ resource "google_container_cluster" "cluster" { node_version = "${var.k8s_version}" } +resource "null_resource" "kubectl" { + count = "${var.init_cli ? 1 : 0 }" + + triggers { + cluster = "${google_container_cluster.cluster.id}" + } + + # On creation, we want to setup the kubectl credentials. The easiest way + # to do this is to shell out to gcloud. + provisioner "local-exec" { + command = "gcloud container clusters get-credentials --zone=${var.zone} ${google_container_cluster.cluster.name}" + } + + # On destroy we want to try to clean up the kubectl credentials. This + # might fail if the credentials are already cleaned up or something so we + # want this to continue on failure. Generally, this works just fine since + # it only operates on local data. + provisioner "local-exec" { + when = "destroy" + on_failure = "continue" + command = "kubectl config get-clusters | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-cluster" + } + + provisioner "local-exec" { + when = "destroy" + on_failure = "continue" + command = "kubectl config get-contexts | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-context" + } +} + +resource "null_resource" "helm" { + count = "${var.init_cli ? 1 : 0 }" + + triggers { + cluster = "${google_container_cluster.cluster.id}" + } + + provisioner "local-exec" { + command = < Date: Mon, 20 Aug 2018 16:17:46 -0700 Subject: [PATCH 011/739] test/terraform: can't install helm until kubectl is configured --- test/terraform/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/test/terraform/main.tf b/test/terraform/main.tf index 64be711bd7..dec20cf17d 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -52,6 +52,7 @@ resource "null_resource" "kubectl" { resource "null_resource" "helm" { count = "${var.init_cli ? 1 : 0 }" + depends_on = ["null_resource.kubectl"] triggers { cluster = "${google_container_cluster.cluster.id}" From 37351656b028f3fbe0427c788f3bb03113c4f548 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 20 Aug 2018 16:22:42 -0700 Subject: [PATCH 012/739] Move tests back directly into test/ --- test/{acceptance => }/_helpers.bash | 0 test/{acceptance => }/server.bats | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/{acceptance => }/_helpers.bash (100%) rename test/{acceptance => }/server.bats (100%) diff --git a/test/acceptance/_helpers.bash b/test/_helpers.bash similarity index 100% rename from test/acceptance/_helpers.bash rename to test/_helpers.bash diff --git a/test/acceptance/server.bats b/test/server.bats similarity index 100% rename from test/acceptance/server.bats rename to test/server.bats From 803a22e51e744581198792d9dd211793cca27e9a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 20 Aug 2018 17:03:28 -0700 Subject: [PATCH 013/739] Update helmignore to ignore the test folder --- .helmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.helmignore b/.helmignore index 4f85fe7a9d..e6d1a61017 100644 --- a/.helmignore +++ b/.helmignore @@ -1,2 +1,3 @@ .git/ .terraform/ +test/ From dc362ea4e462f489c362bf06389dcc79fdfe88cf Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 20 Aug 2018 17:30:52 -0700 Subject: [PATCH 014/739] Ignore bin dirs --- .helmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.helmignore b/.helmignore index e6d1a61017..d1180d2fb7 100644 --- a/.helmignore +++ b/.helmignore @@ -1,3 +1,4 @@ .git/ .terraform/ +bin/ test/ From 3a55af62fe01ad944bff7b90d42f17f83d31be37 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 21 Aug 2018 10:25:37 -0700 Subject: [PATCH 015/739] Allow overridable inject image, test images --- templates/connect-inject-deployment.yaml | 2 +- test/_helpers.bash | 15 +++++++++++++-- values.yaml | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index c15a5b0c88..aced776598 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -27,7 +27,7 @@ spec: spec: containers: - name: sidecar-injector - image: us.gcr.io/mitchellh-k8s/consul-k8s:latest + image: "{{ .Values.connectInject.image }}" env: - name: NAMESPACE valueFrom: diff --git a/test/_helpers.bash b/test/_helpers.bash index 521a10a124..b79f49114c 100644 --- a/test/_helpers.bash +++ b/test/_helpers.bash @@ -3,9 +3,20 @@ name_prefix() { printf "consul" } -# helm_install installs the Consul chart. +# helm_install installs the Consul chart. This will source overridable +# values from the "values.yaml" file in this directory. This can be set +# by CI or other environments to do test-specific overrides. Note that its +# easily possible to break tests this way so be careful. helm_install() { - helm install --name consul --wait ${BATS_TEST_DIRNAME}/.. + local values="${BATS_TEST_DIRNAME}/values.yaml" + if [ ! -f "${values}" ]; then + touch $values + fi + + helm install -f ${values} \ + --name consul \ + --wait \ + ${BATS_TEST_DIRNAME}/.. } # helm_delete deletes the Consul chart and all resources. diff --git a/values.yaml b/values.yaml index e8f316b156..cf22426266 100644 --- a/values.yaml +++ b/values.yaml @@ -61,6 +61,7 @@ client: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: true + image: "us.gcr.io/mitchellh-k8s/consul-k8s:latest" default: false # true will inject by default, otherwise requires annotation caBundle: "" # empty will auto generate the bundle From 7ff71983f1c82d952ea8e484e3f6f45ba81458ea Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 21 Aug 2018 10:51:40 -0700 Subject: [PATCH 016/739] test/docker: add jq to the Test dockerfile --- test/docker/Test.dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/docker/Test.dockerfile b/test/docker/Test.dockerfile index 505ce3e55f..93bff9f748 100644 --- a/test/docker/Test.dockerfile +++ b/test/docker/Test.dockerfile @@ -19,7 +19,8 @@ RUN apk update && apk add --no-cache --virtual .build-deps \ bash \ openssl \ python \ - git + git \ + jq # gcloud RUN curl -OL https://dl.google.com/dl/cloudsdk/channels/rapid/install_google_cloud_sdk.bash && \ From 3a61646b1d1e9e11a7234696888ca491906092e0 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 2 Sep 2018 16:19:11 -0700 Subject: [PATCH 017/739] Add global.enabled to disable all components by default --- templates/client-daemonset.yaml | 2 +- templates/connect-inject-deployment.yaml | 2 +- templates/connect-inject-mutatingwebhook.yaml | 2 +- templates/connect-inject-service.yaml | 2 +- templates/server-config-configmap.yaml | 2 +- templates/server-disruptionbudget.yaml | 2 +- templates/server-service.yaml | 2 +- templates/server-statefulset.yaml | 2 +- templates/ui-service.yaml | 2 +- values.yaml | 17 ++++++++++++----- 10 files changed, 21 insertions(+), 14 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index c32d48e9d2..be50c9c3ae 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -1,5 +1,5 @@ # DaemonSet to run the Consul clients on every node. -{{- if .Values.client.enabled }} +{{- if (default .Values.client.enabled .Values.global.enabled) }} apiVersion: apps/v1 kind: DaemonSet metadata: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index aced776598..98dab69e33 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -1,5 +1,5 @@ # The deployment for running the Connect sidecar injector -{{- if .Values.connectInject.enabled }} +{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 387e4fb910..50ff573e55 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -1,5 +1,5 @@ # The MutatingWebhookConfiguration to enable the Connect injector. -{{- if (.Values.connectInject.enabled) and (.Values.connectInject.caBundle) }} +{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: diff --git a/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml index 65c2efaeae..df27d59d78 100644 --- a/templates/connect-inject-service.yaml +++ b/templates/connect-inject-service.yaml @@ -1,5 +1,5 @@ # The service for the Connect sidecar injector -{{- if .Values.connectInject.enabled }} +{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} apiVersion: v1 kind: Service metadata: diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 7d1c7fd3a2..d1ed4cd421 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -1,5 +1,5 @@ # StatefulSet to run the actual Consul server cluster. -{{- if .Values.server.enabled }} +{{- if (default .Values.server.enabled .Values.global.enabled) }} apiVersion: v1 kind: ConfigMap metadata: diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index f06087af63..252b0c6acb 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -1,6 +1,6 @@ # PodDisruptionBudget to prevent degrading the server cluster through # voluntary cluster changes. -{{- if (.Values.server.enabled) and (.Values.server.disruptionBudget.enabled) }} +{{- if (and (default .Values.server.enabled .Values.global.enabled) (default .Values.server.disruptionBudget.enabled .Values.global.enabled)) }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 5e02384738..79badf8aca 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -3,7 +3,7 @@ # the agent is installed locally on the node and the NODE_IP should be used. # If the node can't run a Consul agent, then this service can be used to # communicate directly to a server agent. -{{- if .Values.server.enabled }} +{{- if (default .Values.server.enabled .Values.global.enabled) }} apiVersion: v1 kind: Service metadata: diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 728e9a914a..3ef66c4a83 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -1,5 +1,5 @@ # StatefulSet to run the actual Consul server cluster. -{{- if .Values.server.enabled }} +{{- if (default .Values.server.enabled .Values.global.enabled) }} apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index d2fd328531..dddba1739a 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -3,7 +3,7 @@ # the agent is installed locally on the node and the NODE_IP should be used. # If the node can't run a Consul agent, then this service can be used to # communicate directly to a server agent. -{{- if (.Values.server.enabled) and (.Values.ui.enabled) and (.Values.ui.service) }} +{{- if (and (default .Values.server.enabled .Values.global.enabled) (default .Values.ui.enabled .Values.global.enabled) (default .Values.ui.service .Values.global.enabled)) }} apiVersion: v1 kind: Service metadata: diff --git a/values.yaml b/values.yaml index cf22426266..1900e8e1cb 100644 --- a/values.yaml +++ b/values.yaml @@ -4,12 +4,19 @@ # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. +global: + # enabled is the master enabled switch. Setting this to true or false + # will enable or disable all the components within this chart by default. + # Each component can be overridden using the component-specific "enabled" + # value. + enabled: true + common: # Domain to register the Consul DNS server to listen for. domain: consul server: - enabled: true + enabled: null image: "consul:1.2.2" replicas: 3 bootstrapExpect: 3 # Should <= replicas count @@ -39,7 +46,7 @@ server: # disruptionBudget enables the creation of a PodDisruptionBudget to # prevent voluntary degrading of the Consul server cluster. disruptionBudget: - enabled: true + enabled: null # maxUnavailable will default to (n/2)-1 where n is the number of # replicas. If you'd like a custom value, you can specify an override here. @@ -54,13 +61,13 @@ server: # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. client: - enabled: true + enabled: null image: "consul:1.2.2" join: null # ConnectInject will enable the automatic Connect sidecar injector. connectInject: - enabled: true + enabled: null image: "us.gcr.io/mitchellh-k8s/consul-k8s:latest" default: false # true will inject by default, otherwise requires annotation caBundle: "" # empty will auto generate the bundle @@ -97,7 +104,7 @@ ui: # on the server nodes. This makes UI access via the service below (if # enabled) predictable rather than "any node" if you're running Consul # clients as well. - enabled: true + enabled: null # True if you want to create a Service entry for the Consul UI. # From d2558a0be32aa1ab340cc22926036d96299e651f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 2 Sep 2018 16:19:45 -0700 Subject: [PATCH 018/739] use globals.domain instead of common in case we refactor later --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- values.yaml | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index be50c9c3ae..e363430fd4 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -70,7 +70,7 @@ spec: {{- end }} {{- end }} {{- end }} - -domain={{ .Values.common.domain }} + -domain={{ .Values.global.domain }} volumeMounts: - name: data mountPath: /consul/data diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 3ef66c4a83..9a0097e5a8 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -77,7 +77,7 @@ spec: -config-dir=/consul/config \ -datacenter={{ .Values.server.datacenter }} \ -data-dir=/consul/data \ - -domain={{ .Values.common.domain }} \ + -domain={{ .Values.global.domain }} \ {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ {{- end }} diff --git a/values.yaml b/values.yaml index 1900e8e1cb..dbc256eb61 100644 --- a/values.yaml +++ b/values.yaml @@ -11,7 +11,6 @@ global: # value. enabled: true -common: # Domain to register the Consul DNS server to listen for. domain: consul From 83fc9d981c637a91a1c9c545d060046485e1545a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 08:42:25 -0700 Subject: [PATCH 019/739] add unit tests that use `helm template` --- templates/server-config-configmap.yaml | 2 +- test/{ => acceptance}/_helpers.bash | 0 test/{ => acceptance}/server.bats | 0 test/docker/Test.dockerfile | 6 ++- test/unit/_helpers.bash | 4 ++ test/unit/server.bats | 53 ++++++++++++++++++++++++++ values.yaml | 2 +- 7 files changed, 64 insertions(+), 3 deletions(-) rename test/{ => acceptance}/_helpers.bash (100%) rename test/{ => acceptance}/server.bats (100%) create mode 100644 test/unit/_helpers.bash create mode 100755 test/unit/server.bats diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index d1ed4cd421..41b1f2f1c4 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -1,5 +1,5 @@ # StatefulSet to run the actual Consul server cluster. -{{- if (default .Values.server.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: v1 kind: ConfigMap metadata: diff --git a/test/_helpers.bash b/test/acceptance/_helpers.bash similarity index 100% rename from test/_helpers.bash rename to test/acceptance/_helpers.bash diff --git a/test/server.bats b/test/acceptance/server.bats similarity index 100% rename from test/server.bats rename to test/acceptance/server.bats diff --git a/test/docker/Test.dockerfile b/test/docker/Test.dockerfile index 93bff9f748..51cc166e89 100644 --- a/test/docker/Test.dockerfile +++ b/test/docker/Test.dockerfile @@ -1,4 +1,4 @@ -# This Dockerfile installs all the dependencies necessary to run the +# This Dockerfile installs all the dependencies necessary to run the unit and # acceptance tests. This image also contains gcloud so you can run tests # against a GKE cluster easily. # @@ -19,9 +19,13 @@ RUN apk update && apk add --no-cache --virtual .build-deps \ bash \ openssl \ python \ + py-pip \ git \ jq +# yq +RUN pip install yq + # gcloud RUN curl -OL https://dl.google.com/dl/cloudsdk/channels/rapid/install_google_cloud_sdk.bash && \ bash install_google_cloud_sdk.bash --disable-prompts --install-dir='/root/' && \ diff --git a/test/unit/_helpers.bash b/test/unit/_helpers.bash new file mode 100644 index 0000000000..530b66e8c3 --- /dev/null +++ b/test/unit/_helpers.bash @@ -0,0 +1,4 @@ +# chart_dir returns the directory for the chart +chart_dir() { + echo ${BATS_TEST_DIRNAME}/../.. +} diff --git a/test/unit/server.bats b/test/unit/server.bats new file mode 100755 index 0000000000..43eb2547ac --- /dev/null +++ b/test/unit/server.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/ConfigMap: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ConfigMap: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ConfigMap: disable with server.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: extraConfig is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'server.extraConfig="{\"hello\": \"world\"}"' \ + . | tee /dev/stderr | + yq '.data["extra-from-values.json"] | match("world") | length' | tee /dev/stderr) + [ ! -z "${actual}" ] +} diff --git a/values.yaml b/values.yaml index dbc256eb61..0dbdaa3e85 100644 --- a/values.yaml +++ b/values.yaml @@ -15,7 +15,7 @@ global: domain: consul server: - enabled: null + enabled: "-" image: "consul:1.2.2" replicas: 3 bootstrapExpect: 3 # Should <= replicas count From fc30ae877e577950b109053be5af0056d9df6c59 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 08:58:19 -0700 Subject: [PATCH 020/739] test/unit: test DisruptionBudget --- templates/server-disruptionbudget.yaml | 2 +- .../{server.bats => server-configmap.bats} | 0 test/unit/server-disruptionbudget.bats | 63 +++++++++++++++++++ values.yaml | 2 +- 4 files changed, 65 insertions(+), 2 deletions(-) rename test/unit/{server.bats => server-configmap.bats} (100%) create mode 100755 test/unit/server-disruptionbudget.bats diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index 252b0c6acb..0470de73bd 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -1,6 +1,6 @@ # PodDisruptionBudget to prevent degrading the server cluster through # voluntary cluster changes. -{{- if (and (default .Values.server.enabled .Values.global.enabled) (default .Values.server.disruptionBudget.enabled .Values.global.enabled)) }} +{{- if (and .Values.server.disruptionBudget.enabled (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: diff --git a/test/unit/server.bats b/test/unit/server-configmap.bats similarity index 100% rename from test/unit/server.bats rename to test/unit/server-configmap.bats diff --git a/test/unit/server-disruptionbudget.bats b/test/unit/server-disruptionbudget.bats new file mode 100755 index 0000000000..c2f2e988f0 --- /dev/null +++ b/test/unit/server-disruptionbudget.bats @@ -0,0 +1,63 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/DisruptionBudget: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/DisruptionBudget: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/DisruptionBudget: disable with server.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/DisruptionBudget: disable with server.disruptionBudget.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.disruptionBudget.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/DisruptionBudget: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/DisruptionBudget: correct maxUnavailable with n=3" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=3' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "0" ] +} diff --git a/values.yaml b/values.yaml index 0dbdaa3e85..1b31abccc1 100644 --- a/values.yaml +++ b/values.yaml @@ -45,7 +45,7 @@ server: # disruptionBudget enables the creation of a PodDisruptionBudget to # prevent voluntary degrading of the Consul server cluster. disruptionBudget: - enabled: null + enabled: true # maxUnavailable will default to (n/2)-1 where n is the number of # replicas. If you'd like a custom value, you can specify an override here. From 0010bd014b3289941689c248b0ed49fe225f84f3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:02:42 -0700 Subject: [PATCH 021/739] test/unit: server Service --- templates/server-service.yaml | 2 +- test/unit/server-service.bats | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100755 test/unit/server-service.bats diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 79badf8aca..ef3b40b2f4 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -3,7 +3,7 @@ # the agent is installed locally on the node and the NODE_IP should be used. # If the node can't run a Consul agent, then this service can be used to # communicate directly to a server agent. -{{- if (default .Values.server.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: v1 kind: Service metadata: diff --git a/test/unit/server-service.bats b/test/unit/server-service.bats new file mode 100755 index 0000000000..024314983f --- /dev/null +++ b/test/unit/server-service.bats @@ -0,0 +1,60 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/Service: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/Service: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/Service: disable with server.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/Service: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +# This can be seen as testing just what we put into the YAML raw, but +# this is such an important part of making everything work we verify it here. +@test "server/Service: tolerates unready endpoints" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + . | tee /dev/stderr | + yq -r '.metadata.annotations["service.alpha.kubernetes.io/tolerate-unready-endpoints"]' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/server-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.publishNotReadyAddresses' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From 64f43108f7571033b1eb40128d4ee152bdde095f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:05:59 -0700 Subject: [PATCH 022/739] test/unit: server StatefulSet --- templates/server-statefulset.yaml | 2 +- test/unit/server-statefulset.bats | 69 +++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100755 test/unit/server-statefulset.bats diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 9a0097e5a8..0a6c32b4c3 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -1,5 +1,5 @@ # StatefulSet to run the actual Consul server cluster. -{{- if (default .Values.server.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats new file mode 100755 index 0000000000..e8b1c7a48d --- /dev/null +++ b/test/unit/server-statefulset.bats @@ -0,0 +1,69 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/StatefulSet: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: disable with server.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: no updateStrategy when not updating" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.updateStrategy' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/StatefulSet: updateStrategy during update" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.updatePartition=2' \ + . | tee /dev/stderr | + yq -r '.spec.updateStrategy.type' | tee /dev/stderr) + [ "${actual}" = "RollingUpdate" ] + + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.updatePartition=2' \ + . | tee /dev/stderr | + yq -r '.spec.updateStrategy.rollingUpdate.partition' | tee /dev/stderr) + [ "${actual}" = "2" ] +} From 5e1e1b1bf63f7be1e29c8c15a03e91c21129edb6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:08:57 -0700 Subject: [PATCH 023/739] test/unit: client DaemonSet --- templates/client-daemonset.yaml | 2 +- test/unit/client-daemonset.yaml | 52 +++++++++++++++++++++++++++++++++ values.yaml | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100755 test/unit/client-daemonset.yaml diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index e363430fd4..a55b1d90eb 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -1,5 +1,5 @@ # DaemonSet to run the Consul clients on every node. -{{- if (default .Values.client.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: apps/v1 kind: DaemonSet metadata: diff --git a/test/unit/client-daemonset.yaml b/test/unit/client-daemonset.yaml new file mode 100755 index 0000000000..0692ec8357 --- /dev/null +++ b/test/unit/client-daemonset.yaml @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/DaemonSet: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: disable with client.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: no updateStrategy when not updating" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.updateStrategy' | tee /dev/stderr) + [ "${actual}" = "null" ] +} diff --git a/values.yaml b/values.yaml index 1b31abccc1..192fdf1ed6 100644 --- a/values.yaml +++ b/values.yaml @@ -60,7 +60,7 @@ server: # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. client: - enabled: null + enabled: "-" image: "consul:1.2.2" join: null From 489a396b4cccda16c32ab86d73e26f5190d5809c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:15:28 -0700 Subject: [PATCH 024/739] test/unit: UI service --- templates/ui-service.yaml | 6 +-- test/unit/ui-service.bats | 94 +++++++++++++++++++++++++++++++++++++++ values.yaml | 7 +-- 3 files changed, 101 insertions(+), 6 deletions(-) create mode 100755 test/unit/ui-service.bats diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index dddba1739a..f0c9784d83 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -3,7 +3,7 @@ # the agent is installed locally on the node and the NODE_IP should be used. # If the node can't run a Consul agent, then this service can be used to # communicate directly to a server agent. -{{- if (and (default .Values.server.enabled .Values.global.enabled) (default .Values.ui.enabled .Values.global.enabled) (default .Values.ui.service .Values.global.enabled)) }} +{{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: v1 kind: Service metadata: @@ -22,7 +22,7 @@ spec: - name: http port: 80 targetPort: 8500 - {{- if .Values.ui.serviceType }} - type: {{ .Values.ui.serviceType }} + {{- if .Values.ui.service.type }} + type: {{ .Values.ui.service.type }} {{- end }} {{- end }} diff --git a/test/unit/ui-service.bats b/test/unit/ui-service.bats new file mode 100755 index 0000000000..df46864418 --- /dev/null +++ b/test/unit/ui-service.bats @@ -0,0 +1,94 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ui/Service: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ui/Service: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + --set 'ui.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ui/Service: disable with server.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ui/Service: disable with ui.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ui/Service: disable with ui.service.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ui/Service: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ui/Service: disable with global.enabled and server.enabled on" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ui/Service: no type by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ui/Service: specified type" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] +} diff --git a/values.yaml b/values.yaml index 192fdf1ed6..7546a17a66 100644 --- a/values.yaml +++ b/values.yaml @@ -103,15 +103,16 @@ ui: # on the server nodes. This makes UI access via the service below (if # enabled) predictable rather than "any node" if you're running Consul # clients as well. - enabled: null + enabled: "-" # True if you want to create a Service entry for the Consul UI. # # serviceType can be used to control the type of service created. For # example, setting this to "LoadBalancer" will create an external load # balancer (for supported K8S installations) to access the UI. - service: true - serviceType: null + service: + enabled: true + type: null test: image: lachlanevenson/k8s-kubectl From fc6d86b96d7fc1d6c4881c9533dd9774963d76bd Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:31:57 -0700 Subject: [PATCH 025/739] test/unit: connect inject Deployment --- templates/connect-inject-deployment.yaml | 2 +- test/unit/connect-inject-deployment.bats | 88 ++++++++++++++++++++++++ values.yaml | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100755 test/unit/connect-inject-deployment.bats diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 98dab69e33..d5b498004c 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -1,5 +1,5 @@ # The deployment for running the Connect sidecar injector -{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats new file mode 100755 index 0000000000..dc9e89a6d6 --- /dev/null +++ b/test/unit/connect-inject-deployment.bats @@ -0,0 +1,88 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInject/Deployment: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: no secretName: no tls-{cert,key}-file set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-cert-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-key-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-auto"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: with secretName: tls-{cert,key}-file set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-cert-file"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-key-file"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-tls-auto"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 7546a17a66..9f2e18318d 100644 --- a/values.yaml +++ b/values.yaml @@ -66,7 +66,7 @@ client: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: - enabled: null + enabled: "-" image: "us.gcr.io/mitchellh-k8s/consul-k8s:latest" default: false # true will inject by default, otherwise requires annotation caBundle: "" # empty will auto generate the bundle From f20934a89def40a135ea2aff84c43c8ba2c1c1d8 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 09:34:28 -0700 Subject: [PATCH 026/739] test/unit: finish inject tests --- templates/connect-inject-mutatingwebhook.yaml | 2 +- templates/connect-inject-service.yaml | 2 +- test/unit/connect-inject-mutatingwebhook.yaml | 43 +++++++++++++++++++ test/unit/connect-inject-service.yaml | 43 +++++++++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100755 test/unit/connect-inject-mutatingwebhook.yaml create mode 100755 test/unit/connect-inject-service.yaml diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 50ff573e55..7d95357870 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -1,5 +1,5 @@ # The MutatingWebhookConfiguration to enable the Connect injector. -{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: diff --git a/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml index df27d59d78..86a13ca2be 100644 --- a/templates/connect-inject-service.yaml +++ b/templates/connect-inject-service.yaml @@ -1,5 +1,5 @@ # The service for the Connect sidecar injector -{{- if (default .Values.connectInject.enabled .Values.global.enabled) }} +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: v1 kind: Service metadata: diff --git a/test/unit/connect-inject-mutatingwebhook.yaml b/test/unit/connect-inject-mutatingwebhook.yaml new file mode 100755 index 0000000000..9de2479921 --- /dev/null +++ b/test/unit/connect-inject-mutatingwebhook.yaml @@ -0,0 +1,43 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInject/MutatingWebhookConfiguration: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-mutatingwebhook.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/MutatingWebhookConfiguration: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-mutatingwebhook.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/MutatingWebhookConfiguration: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-mutatingwebhook.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/MutatingWebhookConfiguration: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-mutatingwebhook.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/connect-inject-service.yaml b/test/unit/connect-inject-service.yaml new file mode 100755 index 0000000000..b510e1a012 --- /dev/null +++ b/test/unit/connect-inject-service.yaml @@ -0,0 +1,43 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInject/Service: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Service: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-service.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Service: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-service.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Service: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-service.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} From 44a9e948c1529743b80206f051f68330d1594719 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 12:57:47 -0700 Subject: [PATCH 027/739] disable the connect injection for now since that is wip --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 9f2e18318d..e95b187a33 100644 --- a/values.yaml +++ b/values.yaml @@ -66,8 +66,8 @@ client: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: - enabled: "-" - image: "us.gcr.io/mitchellh-k8s/consul-k8s:latest" + enabled: false # "-" disable this by default for now until the image is public + image: "TODO" default: false # true will inject by default, otherwise requires annotation caBundle: "" # empty will auto generate the bundle From 6cc5743936a5a7b1ac5039e0ff57512bc08cb590 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 12:59:36 -0700 Subject: [PATCH 028/739] test/acceptance: fix path to chart --- test/acceptance/_helpers.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/acceptance/_helpers.bash b/test/acceptance/_helpers.bash index b79f49114c..a204f6bcf3 100644 --- a/test/acceptance/_helpers.bash +++ b/test/acceptance/_helpers.bash @@ -16,7 +16,7 @@ helm_install() { helm install -f ${values} \ --name consul \ --wait \ - ${BATS_TEST_DIRNAME}/.. + ${BATS_TEST_DIRNAME}/../.. } # helm_delete deletes the Consul chart and all resources. From fefc9298953c7958aa41085a5a8e90a8cc939a38 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 13:02:06 -0700 Subject: [PATCH 029/739] update README for new testing --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9cc9e8f566..a638df6421 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,24 @@ file. These are also fully documented directly on the ## Testing -The Helm charts are tested in two forms: [Bats](https://github.com/bats-core/bats-core) -tests and `helm test` tests. The Bats tests test changing Helm chart values and -the effect on the install. The `helm test` tests verify that a deployed chart -appears healthy. +The Helm chart ships with both unit and acceptance tests. -To run the Bats test: `kubectl` must be configured locally to be authenticated -to a running Kubernetes cluster with Helm installed. With that in place, -just run bats: +The unit tests don't require any active Kubernetes cluster and complete +very quickly. These should be used for fast feedback during development. +The acceptance tests require a Kubernetes cluster with a configured `kubectl`. +Both require [Bats](https://github.com/bats-core/bats-core) and `helm` to +be installed and available on the CLI. - bats ./test +To run the unit tests: -If the tests fail, deployed resources in the Kubernetes cluster may not -be properly cleaned up. We recommend recycling the Kubernetes cluster to + bats ./test/unit + +To run the acceptance tests: + + bats ./test/acceptance + +If the acceptance tests fail, deployed resources in the Kubernetes cluster +may not be properly cleaned up. We recommend recycling the Kubernetes cluster to start from a clean slate. **Note:** There is a Terraform configuration in the From a1528eda463fc947734564652dd38995917fb16d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 3 Sep 2018 16:17:22 -0700 Subject: [PATCH 030/739] Fix unit tests for change to disable connect inject default --- test/unit/connect-inject-deployment.bats | 10 ++++++++-- test/unit/connect-inject-mutatingwebhook.yaml | 4 ++-- test/unit/connect-inject-service.yaml | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index dc9e89a6d6..87143ace6b 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -2,13 +2,13 @@ load _helpers -@test "connectInject/Deployment: enabled by default" { +@test "connectInject/Deployment: disabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } @test "connectInject/Deployment: enable with global.enabled false" { @@ -46,18 +46,21 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-cert-file"))' | tee /dev/stderr) [ "${actual}" = "false" ] local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-key-file"))' | tee /dev/stderr) [ "${actual}" = "false" ] local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-auto"))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -68,6 +71,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.certs.secretName=foo' \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-cert-file"))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -75,6 +79,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.certs.secretName=foo' \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-key-file"))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -82,6 +87,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.certs.secretName=foo' \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-tls-auto"))' | tee /dev/stderr) [ "${actual}" = "false" ] diff --git a/test/unit/connect-inject-mutatingwebhook.yaml b/test/unit/connect-inject-mutatingwebhook.yaml index 9de2479921..1e2142c506 100755 --- a/test/unit/connect-inject-mutatingwebhook.yaml +++ b/test/unit/connect-inject-mutatingwebhook.yaml @@ -2,13 +2,13 @@ load _helpers -@test "connectInject/MutatingWebhookConfiguration: enabled by default" { +@test "connectInject/MutatingWebhookConfiguration: disabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-mutatingwebhook.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } @test "connectInject/MutatingWebhookConfiguration: enable with global.enabled false" { diff --git a/test/unit/connect-inject-service.yaml b/test/unit/connect-inject-service.yaml index b510e1a012..e9a819c75a 100755 --- a/test/unit/connect-inject-service.yaml +++ b/test/unit/connect-inject-service.yaml @@ -2,13 +2,13 @@ load _helpers -@test "connectInject/Service: enabled by default" { +@test "connectInject/Service: disabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-service.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } @test "connectInject/Service: enable with global.enabled false" { From 9d37c9f2f1eca4d32fd04f6a05eb3bd14729b01e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 5 Sep 2018 07:45:54 -0700 Subject: [PATCH 031/739] Support global.image value --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- test/unit/client-daemonset.yaml | 21 +++++++++++++++++++++ test/unit/server-statefulset.bats | 21 +++++++++++++++++++++ values.yaml | 8 ++++++-- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index a55b1d90eb..8a37136cd0 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -37,7 +37,7 @@ spec: containers: - name: consul - image: "{{ .Values.client.image }}" + image: "{{ default .Values.global.image .Values.client.image }}" env: - name: POD_IP valueFrom: diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 0a6c32b4c3..e0786214d5 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -53,7 +53,7 @@ spec: name: {{ template "consul.fullname" . }}-server-config containers: - name: consul - image: "{{ .Values.server.image }}" + image: "{{ default .Values.global.image .Values.server.image }}" env: - name: POD_IP valueFrom: diff --git a/test/unit/client-daemonset.yaml b/test/unit/client-daemonset.yaml index 0692ec8357..612660c2bf 100755 --- a/test/unit/client-daemonset.yaml +++ b/test/unit/client-daemonset.yaml @@ -42,6 +42,27 @@ load _helpers [ "${actual}" = "false" ] } +@test "client/DaemonSet: image defaults to global.image" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.image=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + +@test "client/DaemonSet: image can be overridden with client.image" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.image=foo' \ + --set 'client.image=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + @test "client/DaemonSet: no updateStrategy when not updating" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index e8b1c7a48d..3ad6d4b1e3 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -42,6 +42,27 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/StatefulSet: image defaults to global.image" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.image=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + +@test "server/StatefulSet: image can be overridden with server.image" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.image=foo' \ + --set 'server.image=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + @test "server/StatefulSet: no updateStrategy when not updating" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index e95b187a33..02cf217571 100644 --- a/values.yaml +++ b/values.yaml @@ -14,9 +14,13 @@ global: # Domain to register the Consul DNS server to listen for. domain: consul + # Image is the name (and tag) of the Consul Docker image for clients and + # servers below. This can be overridden per component. + image: "consul:1.2.2" + server: enabled: "-" - image: "consul:1.2.2" + image: null replicas: 3 bootstrapExpect: 3 # Should <= replicas count storage: 10Gi @@ -61,7 +65,7 @@ server: # DC where a single agent is deployed per node. client: enabled: "-" - image: "consul:1.2.2" + image: null join: null # ConnectInject will enable the automatic Connect sidecar injector. From 7baa8543764a104cc065e01103cdd93490730725 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 5 Sep 2018 07:52:27 -0700 Subject: [PATCH 032/739] Add consul-helm repo to Chart.yaml --- Chart.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Chart.yaml b/Chart.yaml index 15fefee5b1..fd6761eeed 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -5,4 +5,5 @@ description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: - https://github.com/hashicorp/consul + - https://github.com/hashicorp/consul-helm - https://github.com/hashicorp/consul-k8s From 71e2fefc6217627e9890cad9bfcb3e446fa435e5 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 8 Sep 2018 07:41:54 -0700 Subject: [PATCH 033/739] extraConfig support for consul clients --- templates/client-config-configmap.yaml | 16 ++++++++ templates/client-daemonset.yaml | 6 +++ test/unit/client-configmap.bats | 53 ++++++++++++++++++++++++++ values.yaml | 5 +++ 4 files changed, 80 insertions(+) create mode 100644 templates/client-config-configmap.yaml create mode 100755 test/unit/client-configmap.bats diff --git a/templates/client-config-configmap.yaml b/templates/client-config-configmap.yaml new file mode 100644 index 0000000000..1bf88baf27 --- /dev/null +++ b/templates/client-config-configmap.yaml @@ -0,0 +1,16 @@ +# ConfigMap with extra configuration specified directly to the chart +# for client agents only. +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-client-config + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +data: + extra-from-values.json: |- +{{ tpl .Values.client.extraConfig . | indent 4 }} +{{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 8a37136cd0..4adbac37cb 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -34,6 +34,9 @@ spec: volumes: - name: data emptyDir: {} + - name: config + configMap: + name: {{ template "consul.fullname" . }}-client-config containers: - name: consul @@ -57,6 +60,7 @@ spec: -advertise="${POD_IP}" \ -bind=0.0.0.0 \ -client=0.0.0.0 \ + -config-dir=/consul/config \ -datacenter={{ .Values.server.datacenter }} \ -data-dir=/consul/data \ {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} @@ -74,6 +78,8 @@ spec: volumeMounts: - name: data mountPath: /consul/data + - name: config + mountPath: /consul/config lifecycle: preStop: exec: diff --git a/test/unit/client-configmap.bats b/test/unit/client-configmap.bats new file mode 100755 index 0000000000..13cd65406a --- /dev/null +++ b/test/unit/client-configmap.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/ConfigMap: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ConfigMap: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ConfigMap: disable with client.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ConfigMap: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ConfigMap: extraConfig is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'client.extraConfig="{\"hello\": \"world\"}"' \ + . | tee /dev/stderr | + yq '.data["extra-from-values.json"] | match("world") | length' | tee /dev/stderr) + [ ! -z "${actual}" ] +} diff --git a/values.yaml b/values.yaml index 02cf217571..a1889ed1e9 100644 --- a/values.yaml +++ b/values.yaml @@ -68,6 +68,11 @@ client: image: null join: null + # extraConfig is a raw string of extra configuration to set with the + # server. This should be JSON or HCL. + extraConfig: | + {} + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public From 08ff19831ac56b07f16d970aec87a812f41c8f2a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 8 Sep 2018 07:50:23 -0700 Subject: [PATCH 034/739] support Values.client.resources --- templates/client-daemonset.yaml | 12 +++++++++++- values.yaml | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 4adbac37cb..50cde56668 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -99,6 +99,16 @@ spec: name: server - containerPort: 8600 name: dns + readinessProbe: + # NOTE(mitchellh): when our HTTP status endpoints support the + # proper status codes, we should switch to that. This is temporary. + exec: + command: + - "/bin/sh" + - "-ec" + - | + curl http://127.0.0.1:8500/v1/status/leader 2>/dev/null | \ + grep -E '".+"' resources: -{{ toYaml .Values.server.resources | indent 12 }} +{{ toYaml .Values.client.resources | indent 12 }} {{- end }} diff --git a/values.yaml b/values.yaml index a1889ed1e9..a31527f83e 100644 --- a/values.yaml +++ b/values.yaml @@ -68,6 +68,11 @@ client: image: null join: null + # Resource requests, limits, etc. for the client cluster placement. This + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + resources: {} + # extraConfig is a raw string of extra configuration to set with the # server. This should be JSON or HCL. extraConfig: | From c9a55882646126e0cce88cfa315a884b4b29edf9 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 8 Sep 2018 07:52:31 -0700 Subject: [PATCH 035/739] Move datacenter to global --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- values.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 50cde56668..4aae0e26f7 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -61,7 +61,7 @@ spec: -bind=0.0.0.0 \ -client=0.0.0.0 \ -config-dir=/consul/config \ - -datacenter={{ .Values.server.datacenter }} \ + -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} {{- range $value := .Values.client.join }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index e0786214d5..8bc2d4a680 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -75,7 +75,7 @@ spec: -bootstrap-expect={{ .Values.server.bootstrapExpect }} \ -client=0.0.0.0 \ -config-dir=/consul/config \ - -datacenter={{ .Values.server.datacenter }} \ + -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ -domain={{ .Values.global.domain }} \ {{- if .Values.server.connect }} diff --git a/values.yaml b/values.yaml index a31527f83e..194bad4984 100644 --- a/values.yaml +++ b/values.yaml @@ -18,6 +18,12 @@ global: # servers below. This can be overridden per component. image: "consul:1.2.2" + # Datacenter is the name of the datacenter that the agents should register + # as. This shouldn't be changed once the Consul cluster is up and running + # since Consul doesn't support an automatic way to change this value + # currently: https://github.com/hashicorp/consul/issues/1858 + datacenter: dc1 + server: enabled: "-" image: null @@ -30,12 +36,6 @@ server: # via the extraConfig setting. connect: true - # Datacenter is the name of the datacenter that the server should register - # as. This shouldn't be changed once the Consul cluster is up and running - # since Consul doesn't support an automatic way to change this value - # currently: https://github.com/hashicorp/consul/issues/1858 - datacenter: dc1 - # Resource requests, limits, etc. for the server cluster placement. This # should map directly to the value of the resources field for a PodSpec. # By default no direct resource request is made. From 2488f92a23339161e8a0e7d0fa9da54ed1229d2f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 8 Sep 2018 08:28:13 -0700 Subject: [PATCH 036/739] Support extraVolumes for server, will add for client soon --- templates/server-statefulset.yaml | 19 ++++++ test/unit/server-statefulset.bats | 97 +++++++++++++++++++++++++++++++ values.yaml | 8 +++ 3 files changed, 124 insertions(+) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 8bc2d4a680..4720e6de74 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -51,6 +51,15 @@ spec: - name: config configMap: name: {{ template "consul.fullname" . }}-server-config + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- end }} containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" @@ -75,6 +84,11 @@ spec: -bootstrap-expect={{ .Values.server.bootstrapExpect }} \ -client=0.0.0.0 \ -config-dir=/consul/config \ + {{- range .Values.server.extraVolumes }} + {{- if .load }} + -config-dir=/consul/userconfig/{{ .name }} + {{- end }} + {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ -domain={{ .Values.global.domain }} \ @@ -93,6 +107,11 @@ spec: mountPath: /consul/data - name: config mountPath: /consul/config + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} lifecycle: preStop: exec: diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 3ad6d4b1e3..8fde43569d 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -63,6 +63,9 @@ load _helpers [ "${actual}" = "bar" ] } +#-------------------------------------------------------------------- +# updateStrategy + @test "server/StatefulSet: no updateStrategy when not updating" { cd `chart_dir` local actual=$(helm template \ @@ -88,3 +91,97 @@ load _helpers yq -r '.spec.updateStrategy.rollingUpdate.partition' | tee /dev/stderr) [ "${actual}" = "2" ] } + +#-------------------------------------------------------------------- +# extraVolumes + +@test "server/StatefulSet: adds extra volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.configMap.name' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + local actual=$(echo $object | + yq -r '.configMap.secretName' | tee /dev/stderr) + [ "${actual}" = "null" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] + + # Doesn't load it + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("userconfig"))) | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "server/StatefulSet: adds extra secret volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=secret' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.secret.name' | tee /dev/stderr) + [ "${actual}" = "null" ] + + local actual=$(echo $object | + yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] + + # Doesn't load it + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("userconfig"))) | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + diff --git a/values.yaml b/values.yaml index 194bad4984..ddee6ac61e 100644 --- a/values.yaml +++ b/values.yaml @@ -60,6 +60,14 @@ server: extraConfig: | {} + # extraVolumes is a list of extra volumes to mount. These will be exposed + # to Consul in the path `/consul/userconfig//`. The value below is + # an array of objects, examples are shown below. + extraVolumes: [] + # - type: secret (or "configMap") + # name: my-secret + # load: false # if true, will add to `-config-dir` to load by Consul + # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. From 2434fe5a433d8616a685140eeef37c8f2ee48c0f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 8 Sep 2018 08:35:07 -0700 Subject: [PATCH 037/739] clients support extraVolumes --- templates/client-daemonset.yaml | 19 ++++++ test/unit/client-daemonset.yaml | 105 ++++++++++++++++++++++++++++++ test/unit/server-statefulset.bats | 11 ++++ values.yaml | 8 +++ 4 files changed, 143 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 4aae0e26f7..394f5b1b59 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -37,6 +37,15 @@ spec: - name: config configMap: name: {{ template "consul.fullname" . }}-client-config + {{- range .Values.client.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- end }} containers: - name: consul @@ -61,6 +70,11 @@ spec: -bind=0.0.0.0 \ -client=0.0.0.0 \ -config-dir=/consul/config \ + {{- range .Values.client.extraVolumes }} + {{- if .load }} + -config-dir=/consul/userconfig/{{ .name }} + {{- end }} + {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} @@ -80,6 +94,11 @@ spec: mountPath: /consul/data - name: config mountPath: /consul/config + {{- range .Values.client.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} lifecycle: preStop: exec: diff --git a/test/unit/client-daemonset.yaml b/test/unit/client-daemonset.yaml index 612660c2bf..bc50dc1cbf 100755 --- a/test/unit/client-daemonset.yaml +++ b/test/unit/client-daemonset.yaml @@ -71,3 +71,108 @@ load _helpers yq -r '.spec.updateStrategy' | tee /dev/stderr) [ "${actual}" = "null" ] } + +#-------------------------------------------------------------------- +# extraVolumes + +@test "client/DaemonSet: adds extra volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.configMap.name' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + local actual=$(echo $object | + yq -r '.configMap.secretName' | tee /dev/stderr) + [ "${actual}" = "null" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] + + # Doesn't load it + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("userconfig"))) | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "client/DaemonSet: adds extra secret volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=secret' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.secret.name' | tee /dev/stderr) + [ "${actual}" = "null" ] + + local actual=$(echo $object | + yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] + + # Doesn't load it + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("userconfig"))) | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "client/DaemonSet: adds loadable volume" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraVolumes[0].type=configMap' \ + --set 'client.extraVolumes[0].name=foo' \ + --set 'client.extraVolumes[0].load=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("/consul/userconfig/foo"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 8fde43569d..32bb0b51ad 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -185,3 +185,14 @@ load _helpers [ "${actual}" = "0" ] } +@test "server/StatefulSet: adds loadable volume" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=configMap' \ + --set 'server.extraVolumes[0].name=foo' \ + --set 'server.extraVolumes[0].load=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | map(select(test("/consul/userconfig/foo"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/values.yaml b/values.yaml index ddee6ac61e..73a3618954 100644 --- a/values.yaml +++ b/values.yaml @@ -86,6 +86,14 @@ client: extraConfig: | {} + # extraVolumes is a list of extra volumes to mount. These will be exposed + # to Consul in the path `/consul/userconfig//`. The value below is + # an array of objects, examples are shown below. + extraVolumes: [] + # - type: secret (or "configMap") + # name: my-secret + # load: false # if true, will add to `-config-dir` to load by Consul + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public From 972a6defc26e14fb31491039c7bb2a9af0839d49 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 10 Sep 2018 09:38:27 -0700 Subject: [PATCH 038/739] Update README --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a638df6421..5e54a61987 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ This repository contains the official HashiCorp Helm chart for installing and configuring Consul on Kubernetes. This chart supports multiple use cases of Consul on Kubernetes depending on the values provided. -Please see the [consul-k8s project](https://github.com/hashicorp/consul-k8s) -for the various ways that Consul integrates with Kubernetes. This Helm chart -installs and configures `consul-k8s` in some cases. +For full documentation on this Helm chart along with all the ways you can +use Consul with Kubernetes, please see the +[Consul and Kubernetes documentation](https://www.consul.io/docs/platform/k8s/index.html). ## Prerequisites @@ -25,7 +25,7 @@ then be installed directly: Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the -[Consul website](https://www.consul.io/docs/). +[Consul website](https://www.consul.io/docs/platform/k8s/helm.html). ## Testing @@ -53,4 +53,5 @@ start from a clean slate. [test/terraform/ directory](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) that can be used to quickly bring up a GKE cluster and configure `kubectl` and `helm` locally. This can be used to quickly spin up a test +cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes cluster. From 0db2be6d10e178cda371c203431fe4c44645b74e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 11 Sep 2018 12:35:16 -0700 Subject: [PATCH 039/739] test: terraform uses data source to get latest GKE version --- test/terraform/main.tf | 8 ++++++-- test/terraform/variables.tf | 5 ----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/test/terraform/main.tf b/test/terraform/main.tf index dec20cf17d..a73df6a717 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -10,14 +10,18 @@ resource "random_id" "suffix" { byte_length = 4 } +data "google_container_engine_versions" "main" { + zone = "${var.zone}" +} + resource "google_container_cluster" "cluster" { name = "consul-k8s-${random_id.suffix.dec}" project = "${var.project}" enable_legacy_abac = true initial_node_count = 5 zone = "${var.zone}" - min_master_version = "${var.k8s_version}" - node_version = "${var.k8s_version}" + min_master_version = "${data.google_container_engine_versions.main.latest_master_version}" + node_version = "${data.google_container_engine_versions.main.latest_node_version}" } resource "null_resource" "kubectl" { diff --git a/test/terraform/variables.tf b/test/terraform/variables.tf index 4a5c70c1fa..c64cf06801 100644 --- a/test/terraform/variables.tf +++ b/test/terraform/variables.tf @@ -1,8 +1,3 @@ -variable "k8s_version" { - default = "1.10.5-gke.4" - description = "The K8S version to use for both master and nodes." -} - variable "project" { description = < Date: Tue, 11 Sep 2018 17:53:02 -0700 Subject: [PATCH 040/739] Add consul-dns service --- templates/client-daemonset.yaml | 2 ++ templates/dns-service.yaml | 26 +++++++++++++++++++ templates/server-statefulset.yaml | 2 ++ test/unit/dns-service.bats | 43 +++++++++++++++++++++++++++++++ values.yaml | 41 +++++++++++++++++------------ 5 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 templates/dns-service.yaml create mode 100755 test/unit/dns-service.bats diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 394f5b1b59..23b98976ec 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -16,6 +16,7 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: client + hasDNS: "true" template: metadata: labels: @@ -23,6 +24,7 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: client + hasDNS: "true" annotations: "consul.hashicorp.com/connect-inject": "false" spec: diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml new file mode 100644 index 0000000000..8f0d30fcde --- /dev/null +++ b/templates/dns-service.yaml @@ -0,0 +1,26 @@ +# Service for Consul DNS. +{{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-dns + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + ports: + - name: dns-tcp + port: 53 + protocol: "TCP" + targetPort: dns + - name: dns-udp + port: 53 + protocol: "UDP" + targetPort: dns + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + hasDNS: "true" +{{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 4720e6de74..7276782be8 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -25,6 +25,7 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: server + hasDNS: "true" template: metadata: labels: @@ -32,6 +33,7 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: server + hasDNS: "true" annotations: "consul.hashicorp.com/connect-inject": "false" spec: diff --git a/test/unit/dns-service.bats b/test/unit/dns-service.bats new file mode 100755 index 0000000000..8acfdcfeb5 --- /dev/null +++ b/test/unit/dns-service.bats @@ -0,0 +1,43 @@ +#!/usr/bin/env bats + +load _helpers + +@test "dns/Service: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "dns/Service: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'global.enabled=false' \ + --set 'dns.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "dns/Service: disable with dns.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'dns.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "dns/Service: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 73a3618954..27bd0a790e 100644 --- a/values.yaml +++ b/values.yaml @@ -94,6 +94,31 @@ client: # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul +# Configuration for DNS configuration within the Kubernetes cluster. +# This creates a service that routes to all agents (client or server) +# for serving DNS requests. This DOES NOT automatically configure kube-dns +# today, so you must still manually configure a `stubDomain` with kube-dns +# for this to have any effect: +# https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers +dns: + enabled: "-" + +ui: + # True if you want to enable the Consul UI. The UI will run only + # on the server nodes. This makes UI access via the service below (if + # enabled) predictable rather than "any node" if you're running Consul + # clients as well. + enabled: "-" + + # True if you want to create a Service entry for the Consul UI. + # + # serviceType can be used to control the type of service created. For + # example, setting this to "LoadBalancer" will create an external load + # balancer (for supported K8S installations) to access the UI. + service: + enabled: true + type: null + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public @@ -128,22 +153,6 @@ connectInject: certName: tls.crt keyName: tls.key -ui: - # True if you want to enable the Consul UI. The UI will run only - # on the server nodes. This makes UI access via the service below (if - # enabled) predictable rather than "any node" if you're running Consul - # clients as well. - enabled: "-" - - # True if you want to create a Service entry for the Consul UI. - # - # serviceType can be used to control the type of service created. For - # example, setting this to "LoadBalancer" will create an external load - # balancer (for supported K8S installations) to access the UI. - service: - enabled: true - type: null - test: image: lachlanevenson/k8s-kubectl imageTag: v1.4.8-bash From 9ef4efc5c48fd1d623184de7e7aeb298d5d58cc3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 11 Sep 2018 19:09:45 -0700 Subject: [PATCH 041/739] client and server must export both TCP and UDP DNS ports --- templates/client-daemonset.yaml | 6 +++++- templates/dns-service.yaml | 4 ++-- templates/server-service.yaml | 9 +++++++-- templates/server-statefulset.yaml | 6 +++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 23b98976ec..10a332cb1d 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -119,7 +119,11 @@ spec: - containerPort: 8300 name: server - containerPort: 8600 - name: dns + name: dns-tcp + protocol: "TCP" + - containerPort: 8600 + name: dns-udp + protocol: "UDP" readinessProbe: # NOTE(mitchellh): when our HTTP status endpoints support the # proper status codes, we should switch to that. This is temporary. diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index 8f0d30fcde..40846fba31 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -14,11 +14,11 @@ spec: - name: dns-tcp port: 53 protocol: "TCP" - targetPort: dns + targetPort: dns-tcp - name: dns-udp port: 53 protocol: "UDP" - targetPort: dns + targetPort: dns-udp selector: app: {{ template "consul.name" . }} release: "{{ .Release.Name }}" diff --git a/templates/server-service.yaml b/templates/server-service.yaml index ef3b40b2f4..902abe0a24 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -46,9 +46,14 @@ spec: - name: server port: 8300 targetPort: 8300 - - name: dns + - name: dns-tcp + protocol: "TCP" + port: 8600 + targetPort: dns-tcp + - name: dns-udp + protocol: "UDP" port: 8600 - targetPort: 8600 + targetPort: dns-udp selector: app: {{ template "consul.name" . }} release: "{{ .Release.Name }}" diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 7276782be8..09ad457797 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -131,7 +131,11 @@ spec: - containerPort: 8300 name: server - containerPort: 8600 - name: dns + name: dns-tcp + protocol: "TCP" + - containerPort: 8600 + name: dns-udp + protocol: "UDP" readinessProbe: # NOTE(mitchellh): when our HTTP status endpoints support the # proper status codes, we should switch to that. This is temporary. From 52e069d67f02a9f55f80dc6d1ebef160e828068a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 11 Sep 2018 19:43:05 -0700 Subject: [PATCH 042/739] Fix up `helm test` to use the local client --- templates/tests/test-config.yaml | 9 ------ templates/tests/test-runner.yaml | 52 ++++++++++++++------------------ values.yaml | 4 --- 3 files changed, 23 insertions(+), 42 deletions(-) delete mode 100644 templates/tests/test-config.yaml diff --git a/templates/tests/test-config.yaml b/templates/tests/test-config.yaml deleted file mode 100644 index 26fef08f25..0000000000 --- a/templates/tests/test-config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "consul.fullname" . }}-tests -data: - run.sh: |- - @test "Testing Consul cluster has quorum" { - [ `kubectl exec {{ template "consul.fullname" . }}-server-0 consul members --namespace={{ .Release.Namespace }} | grep server | wc -l` -ge "3" ] - } diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 65b6b6081a..473b873823 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -1,37 +1,31 @@ apiVersion: v1 kind: Pod metadata: - name: "{{ .Release.Name }}-test-{{ randAlphaNum 5 | lower }}" + name: "{{ template "consul.fullname" . }}-test-{{ randAlphaNum 5 | lower }}" + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} annotations: "helm.sh/hook": test-success spec: - initContainers: - - name: test-framework - image: dduportal/bats:0.4.0 - command: - - "bash" - - "-c" - - | - set -ex - # copy bats to tools dir - cp -R /usr/local/libexec/ /tools/bats/ - volumeMounts: - - mountPath: /tools - name: tools containers: - - name: {{ .Release.Name }}-test - image: {{ .Values.test.image }}:{{ .Values.test.imageTag }} - command: ["/tools/bats/bats", "-t", "/tests/run.sh"] - volumeMounts: - - mountPath: /tests - name: tests - readOnly: true - - mountPath: /tools - name: tools - volumes: - - name: tests - configMap: - name: {{ template "consul.fullname" . }}-tests - - name: tools - emptyDir: {} + - name: consul-test + image: "{{ .Values.global.image }}" + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + command: + - "/bin/sh" + - "-ec" + - | + export VALUE="{{randAlphaNum 24 | lower }}" + export CONSUL_HTTP_ADDR="${HOST_IP}:8500" + consul kv delete _consul_helm_test + consul kv put _consul_helm_test $VALUE + [ `consul kv get _consul_helm_test` = "$VALUE" ] + consul kv delete _consul_helm_test restartPolicy: Never diff --git a/values.yaml b/values.yaml index 27bd0a790e..55e6dfe461 100644 --- a/values.yaml +++ b/values.yaml @@ -152,7 +152,3 @@ connectInject: # defaults but can be customized if necessary. certName: tls.crt keyName: tls.key - -test: - image: lachlanevenson/k8s-kubectl - imageTag: v1.4.8-bash From 78ae63636f144515f830e34885771bf7b99d91b8 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 12 Sep 2018 08:47:27 -0700 Subject: [PATCH 043/739] Update README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e54a61987..980f515a20 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,10 @@ of this README. Please refer to the Kubernetes and Helm documentation. ## Usage For now, we do not host a Chart repository. To use the charts, you must -download this repository and unpack it into a directory. Assuming this -repository was unpacked into the directory `consul-helm`, the chart can +download this repository and unpack it into a directory. Either +[download a tagged release](https://github.com/hashicorp/consul-helm/releases) or +use `git checkout` to a tagged release. +Assuming this repository was unpacked into the directory `consul-helm`, the chart can then be installed directly: helm install ./consul-helm From d3351086d234ae3ea715baa9013831d5d1b578c5 Mon Sep 17 00:00:00 2001 From: Jack Pearkes Date: Thu, 13 Sep 2018 09:27:29 -0700 Subject: [PATCH 044/739] values: update to consul 1.2.3 Consul 1.2.3 was released today. --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 55e6dfe461..03f38a1cfc 100644 --- a/values.yaml +++ b/values.yaml @@ -16,7 +16,7 @@ global: # Image is the name (and tag) of the Consul Docker image for clients and # servers below. This can be overridden per component. - image: "consul:1.2.2" + image: "consul:1.2.3" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 193f1dddad84c3f51387f2119926549d6f080093 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 13 Sep 2018 14:44:08 -0700 Subject: [PATCH 045/739] Correct chart casing for our usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 980f515a20..9f19fc81a3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ of this README. Please refer to the Kubernetes and Helm documentation. ## Usage -For now, we do not host a Chart repository. To use the charts, you must +For now, we do not host a chart repository. To use the charts, you must download this repository and unpack it into a directory. Either [download a tagged release](https://github.com/hashicorp/consul-helm/releases) or use `git checkout` to a tagged release. From 102e220e070379215413f005fdb91e6d5f4b62fb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 13 Sep 2018 14:48:40 -0700 Subject: [PATCH 046/739] update README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 9f19fc81a3..2f4ec50334 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,14 @@ To use the charts here, [Helm](https://helm.sh/) must be installed in your Kubernetes cluster. Setting up Kubernetes and Helm and is outside the scope of this README. Please refer to the Kubernetes and Helm documentation. +The versions required are: + + * **Helm 2.10+** - This is the earliest version of Helm tested. It is possible + it works with earlier versions but this chart is untested for those versions. + * **Kubernetes 2.9+** - This is the earliest version of Kubernetes tested. + It is possible that this chart works with earlier versions but it is + untested. Other versions verified are Kubernetes 2.10, 2.11. + ## Usage For now, we do not host a chart repository. To use the charts, you must From 7ffe68b388b004afaac158a5ac2558f5d0eeb93c Mon Sep 17 00:00:00 2001 From: Josh Reichardt Date: Fri, 14 Sep 2018 09:06:52 -0700 Subject: [PATCH 047/739] Add link to correct yq in README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f4ec50334..2b0184f491 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,9 @@ The Helm chart ships with both unit and acceptance tests. The unit tests don't require any active Kubernetes cluster and complete very quickly. These should be used for fast feedback during development. The acceptance tests require a Kubernetes cluster with a configured `kubectl`. -Both require [Bats](https://github.com/bats-core/bats-core) and `helm` to -be installed and available on the CLI. +Both require [Bats](https://github.com/bats-core/bats-core) and `helm` to be +installed and available on the CLI. The unit tests also require the correct +version of [yq](https://pypi.org/project/yq/) if running locally. To run the unit tests: From 9a8ecfa276977f5e6f73e5241854de48bd4b75a1 Mon Sep 17 00:00:00 2001 From: Sean Johnson Date: Sat, 15 Sep 2018 13:10:38 -0500 Subject: [PATCH 048/739] Fixed typo in Kubernetes versions The README referenced Kubernetes major versions **2** instead of **1**. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f4ec50334..7467cec262 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,9 @@ The versions required are: * **Helm 2.10+** - This is the earliest version of Helm tested. It is possible it works with earlier versions but this chart is untested for those versions. - * **Kubernetes 2.9+** - This is the earliest version of Kubernetes tested. + * **Kubernetes 1.9+** - This is the earliest version of Kubernetes tested. It is possible that this chart works with earlier versions but it is - untested. Other versions verified are Kubernetes 2.10, 2.11. + untested. Other versions verified are Kubernetes 1.10, 1.11. ## Usage From febaab96faaa1a24506ccb3fe162c0a1330d0acf Mon Sep 17 00:00:00 2001 From: Maciek Misztal Date: Thu, 20 Sep 2018 21:35:08 +0200 Subject: [PATCH 049/739] #7 added an optional storageClass to the server-statefuset --- templates/server-statefulset.yaml | 3 +++ values.yaml | 1 + 2 files changed, 4 insertions(+) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 09ad457797..cd9e008459 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -160,4 +160,7 @@ spec: resources: requests: storage: {{ .Values.server.storage }} + {{- if .Values.server.storageClass }} + storageClassName: {{ .Values.server.storageClass }} + {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index 03f38a1cfc..1404bdc229 100644 --- a/values.yaml +++ b/values.yaml @@ -30,6 +30,7 @@ server: replicas: 3 bootstrapExpect: 3 # Should <= replicas count storage: 10Gi + #storageClass: default # <= name of the storage class to use # connect will enable Connect on all the servers, initializing a CA # for Connect-related connections. Other customizations can be done From 85538787e7cc17ab7b2f3ae5e78515a02dfd1fc7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 22 Sep 2018 09:57:36 -0700 Subject: [PATCH 050/739] Unit tests for storageClass --- test/unit/server-statefulset.bats | 24 ++++++++++++++++++++++++ values.yaml | 7 ++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 32bb0b51ad..edce61671d 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -196,3 +196,27 @@ load _helpers yq -r '.spec.template.spec.containers[0].command | map(select(test("/consul/userconfig/foo"))) | length' | tee /dev/stderr) [ "${actual}" = "1" ] } + +#-------------------------------------------------------------------- +# updateStrategy + +@test "server/StatefulSet: no storageClass on claim by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + + +@test "server/StatefulSet: can set storageClass" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.storageClass=foo' \ + . | tee /dev/stderr | + yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + diff --git a/values.yaml b/values.yaml index 1404bdc229..925277d57d 100644 --- a/values.yaml +++ b/values.yaml @@ -29,8 +29,13 @@ server: image: null replicas: 3 bootstrapExpect: 3 # Should <= replicas count + + # storage and storageClass are the settings for configuring stateful + # storage for the server pods. storage should be set to the disk size of + # the attached volume. storageClass is the class of storage which defaults + # to null (the Kube cluster will pick the default). storage: 10Gi - #storageClass: default # <= name of the storage class to use + storageClass: null # connect will enable Connect on all the servers, initializing a CA # for Connect-related connections. Other customizations can be done From 14ff53b04690accca539e480d204d4b909827f72 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 22 Sep 2018 09:59:41 -0700 Subject: [PATCH 051/739] Add CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..6bc7fcae40 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +## Unreleased + +Improvements: + + * server: support `storageClass` [GH-7] + +## 0.1.0 + +Initial release From f39ac481aa01802666377ca6c1611feec3461eb9 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 22 Sep 2018 16:06:24 -0700 Subject: [PATCH 052/739] syncCatalog templates --- templates/sync-catalog-deployment.yaml | 54 +++++++++++++ test/unit/sync-catalog-deployment.bats | 101 +++++++++++++++++++++++++ values.yaml | 18 +++++ 3 files changed, 173 insertions(+) create mode 100644 templates/sync-catalog-deployment.yaml create mode 100755 test/unit/sync-catalog-deployment.bats diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml new file mode 100644 index 0000000000..6568cb9b2c --- /dev/null +++ b/templates/sync-catalog-deployment.yaml @@ -0,0 +1,54 @@ +# The deployment for running the Connect sidecar injector +{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: sync-catalog + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: sync-catalog + spec: + containers: + - name: consul-sync-catalog + image: "{{ .Values.syncCatalog.image }}" + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s sync-catalog \ + -http-addr=${HOST_IP}:8500 \ + {{- if (not .Values.syncCatalog.toConsul) }} + -to-consul=false \ + {{- end }} + {{- if (not .Values.syncCatalog.toK8S) }} + -to-k8s=false \ + {{- end }} + -consul-domain={{ .Values.global.domain }} \ + -k8s-write-namespace=${NAMESPACE} +{{- end }} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats new file mode 100755 index 0000000000..842b94cf0f --- /dev/null +++ b/test/unit/sync-catalog-deployment.bats @@ -0,0 +1,101 @@ +#!/usr/bin/env bats + +load _helpers + +@test "syncCatalog/Deployment: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: disable with syncCatalog.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# toConsul and toK8S + +@test "syncCatalog/Deployment: bidirectional by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-consul"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: to-k8s only" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-consul=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: to-consul only" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toK8S=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toK8S=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-consul"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 925277d57d..4c0bdc4d26 100644 --- a/values.yaml +++ b/values.yaml @@ -125,6 +125,24 @@ ui: enabled: true type: null +# syncCatalog will run the catalog sync process to sync K8S with Consul +# services. This can run bidirectional (default) or unidirectionally (Consul +# to K8S or K8S to Consul only). +# +# This process assumes that a Consul agent is available on the host IP. +# This is done automatically if clients are enabled. If clients are not +# enabled then set the node selection so that it chooses a node with a +# Consul agent. +syncCatalog: + # True if you want to enable the catalog sync. "-" for default. + enabled: "-" + image: null + + # toConsul and toK8S control whether syncing is enabled to Consul or K8S + # as a destination. If both of these are disabled, the sync will do nothing. + toConsul: true + toK8S: true + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public From 0931239bee9f555cb5e881ee61c4f668d9459a00 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 22 Sep 2018 16:45:51 -0700 Subject: [PATCH 053/739] disable catalog sync by default --- test/unit/sync-catalog-deployment.bats | 4 ++-- values.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 842b94cf0f..17c0f5801c 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -2,13 +2,13 @@ load _helpers -@test "syncCatalog/Deployment: enabled by default" { +@test "syncCatalog/Deployment: disabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } @test "syncCatalog/Deployment: enable with global.enabled false" { diff --git a/values.yaml b/values.yaml index 4c0bdc4d26..897f77d653 100644 --- a/values.yaml +++ b/values.yaml @@ -135,7 +135,7 @@ ui: # Consul agent. syncCatalog: # True if you want to enable the catalog sync. "-" for default. - enabled: "-" + enabled: false image: null # toConsul and toK8S control whether syncing is enabled to Consul or K8S From 560c461c9bd818d618e1f08e66d4c721c5a00d94 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 25 Sep 2018 09:10:05 -0500 Subject: [PATCH 054/739] ability to specify prefix for catalog sync --- templates/sync-catalog-deployment.yaml | 3 +++ test/unit/sync-catalog-deployment.bats | 24 ++++++++++++++++++++++++ values.yaml | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 6568cb9b2c..0eb863b40c 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -50,5 +50,8 @@ spec: -to-k8s=false \ {{- end }} -consul-domain={{ .Values.global.domain }} \ + {{- if .Values.syncCatalog.k8sPrefix }} + -k8s-service-prefix="{{ .Values.syncCatalog.k8sPrefix}}" \ + {{- end }} -k8s-write-namespace=${NAMESPACE} {{- end }} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 17c0f5801c..b623543034 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -99,3 +99,27 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-to-consul"))' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# k8sPrefix + +@test "syncCatalog/Deployment: no k8sPrefix by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-k8s-service-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: can specify k8sPrefix" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.k8sPrefix=foo-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-k8s-service-prefix=\"foo-\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 897f77d653..f88d989aad 100644 --- a/values.yaml +++ b/values.yaml @@ -143,6 +143,11 @@ syncCatalog: toConsul: true toK8S: true + # k8sPrefix is the service prefix to prepend to services before registering + # with Kubernetes. For example "consul-" will register all services + # prepended with "consul-". + k8sPrefix: null + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public From 71b899159c4a7ff73789e34475455f9c8b80ef42 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 25 Sep 2018 09:19:19 -0500 Subject: [PATCH 055/739] add global.imageK8S for consul-k8s --- templates/sync-catalog-deployment.yaml | 2 +- test/unit/sync-catalog-deployment.bats | 26 ++++++++++++++++++++++++++ values.yaml | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 0eb863b40c..937891d62a 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -27,7 +27,7 @@ spec: spec: containers: - name: consul-sync-catalog - image: "{{ .Values.syncCatalog.image }}" + image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" env: - name: HOST_IP valueFrom: diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index b623543034..c9f0f30bd2 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -42,6 +42,32 @@ load _helpers [ "${actual}" = "false" ] } +#-------------------------------------------------------------------- +# image + +@test "syncCatalog/Deployment: image defaults to global.imageK8S" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'global.imageK8S=bar' \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + +@test "syncCatalog/Deployment: image can be overridden with server.image" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'global.imageK8S=foo' \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.image=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + #-------------------------------------------------------------------- # toConsul and toK8S diff --git a/values.yaml b/values.yaml index f88d989aad..83182d3adc 100644 --- a/values.yaml +++ b/values.yaml @@ -18,6 +18,11 @@ global: # servers below. This can be overridden per component. image: "consul:1.2.3" + # imageK8S is the name (and tag) of the consul-k8s Docker image that + # is used for functionality such as the catalog sync. This can be overridden + # per component below. + imageK8S: "hashicorp/consul-k8s:0.1.0" + # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running # since Consul doesn't support an automatic way to change this value From f77939ee30b84c33c2dcd91b5599ea3b9a7288cf Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 26 Sep 2018 09:42:33 -0500 Subject: [PATCH 056/739] update CHANGELOG --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bc7fcae40..f310eff240 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ## Unreleased -Improvements: +FEATURES: + + * `syncCatalog` can install the [service catalog sync](https://www.hashicorp.com/blog/consul-and-kubernetes-service-catalog-sync) + functionality. + +IMPROVEMENTS: * server: support `storageClass` [GH-7] From 8b57bedd48460b55b53506dccbf6c60e0054e891 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 26 Sep 2018 12:43:21 -0500 Subject: [PATCH 057/739] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f310eff240..9c769c023b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Unreleased +## 0.2.0 (September 26, 2018) FEATURES: From 2db433ed5dd6ec8a839f5e459e4bad9559aafb83 Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 28 Sep 2018 13:36:26 -0500 Subject: [PATCH 058/739] Formatting update Reading the README, this "[test/terraform directory]()" link looked funny. I changed it to "[`test/terraform`]() directory" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fdd18a46d..0eb6ca0cf9 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ may not be properly cleaned up. We recommend recycling the Kubernetes cluster to start from a clean slate. **Note:** There is a Terraform configuration in the -[test/terraform/ directory](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) +[`test/terraform/`](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) directory that can be used to quickly bring up a GKE cluster and configure `kubectl` and `helm` locally. This can be used to quickly spin up a test cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes From ea99e51fc63ddf205b1913d423e6f30ce83b9823 Mon Sep 17 00:00:00 2001 From: Maciek Misztal Date: Sun, 30 Sep 2018 22:44:43 +0200 Subject: [PATCH 059/739] #14 ensured consul agent is using physical node's name --- templates/client-daemonset.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 10a332cb1d..b9efd014ab 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -61,6 +61,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + - name: NODE + valueFrom: + fieldRef: + fieldPath: spec.nodeName command: - "/bin/sh" - "-ec" @@ -68,10 +72,11 @@ spec: CONSUL_FULLNAME="{{template "consul.fullname" . }}" exec /bin/consul agent \ + -node="${NODE}" \ -advertise="${POD_IP}" \ -bind=0.0.0.0 \ -client=0.0.0.0 \ - -config-dir=/consul/config \ + -config-dir=/consul/config \ {{- range .Values.client.extraVolumes }} {{- if .load }} -config-dir=/consul/userconfig/{{ .name }} From a82665e2bc573daa76c9c3b770e19a2067161470 Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Thu, 4 Oct 2018 14:25:49 +1000 Subject: [PATCH 060/739] Configure affinity to be a variable to allow overriding --- templates/server-statefulset.yaml | 11 +++-------- values.yaml | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index cd9e008459..3e088c310d 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -37,15 +37,10 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" spec: + {{- if .Values.server.affinity }} affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: {{ template "consul.name" . }} - release: "{{ .Release.Name }}" - component: server - topologyKey: kubernetes.io/hostname +{{ tpl .Values.server.affinity . | indent 8 }} +{{- end }} terminationGracePeriodSeconds: 10 securityContext: fsGroup: 1000 diff --git a/values.yaml b/values.yaml index 83182d3adc..587c517331 100644 --- a/values.yaml +++ b/values.yaml @@ -79,6 +79,20 @@ server: # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul + # Affinity Settings + # Overriding this will allow deployment to single node services such as + # Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + + # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. From dbeb837e49b109a3b95a5186aad0ea7aca769744 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Oct 2018 22:18:31 -0700 Subject: [PATCH 061/739] connectInject: configurable consul/envoy images, fix container image --- templates/connect-inject-deployment.yaml | 6 ++- test/unit/connect-inject-deployment.bats | 50 ++++++++++++++++++++++++ values.yaml | 9 ++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index d5b498004c..b760a3a6cc 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -27,7 +27,7 @@ spec: spec: containers: - name: sidecar-injector - image: "{{ .Values.connectInject.image }}" + image: "{{ default .Values.global.imageK8S .Values.connectInject.image }}" env: - name: NAMESPACE valueFrom: @@ -41,6 +41,10 @@ spec: consul-k8s inject \ -default-inject={{ .Values.connectInject.default }} \ + -consul-image="{{ default .Values.global.image .Values.connectInject.imageConsul }}" \ + {{ if .Values.connectInject.imageEnvoy -}} + -envoy-image="{{ .Values.connectInject.imageEnvoy }}" \ + {{ end -}} -listen=:8080 \ {{- if .Values.connectInject.certs.secretName }} -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 87143ace6b..18a02a5b3d 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -42,6 +42,56 @@ load _helpers [ "${actual}" = "false" ] } +#-------------------------------------------------------------------- +# consul and envoy images + +@test "connectInject/Deployment: consul-image defaults to global" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.image=foo' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-image=\"foo\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: consul-image can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.image=foo' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.imageConsul=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-image=\"bar\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: envoy-image is not set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-envoy-image"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: envoy-image can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.imageEnvoy=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-envoy-image=\"foo\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# cert secrets + @test "connectInject/Deployment: no secretName: no tls-{cert,key}-file set" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index 83182d3adc..d79d0f6d25 100644 --- a/values.yaml +++ b/values.yaml @@ -156,10 +156,17 @@ syncCatalog: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public - image: "TODO" + image: null default: false # true will inject by default, otherwise requires annotation caBundle: "" # empty will auto generate the bundle + # imageConsul and imageEnvoy can be set to Docker images for Consul and + # Envoy, respectively. If the Consul image is not specified, the global + # default will be used. If the Envoy image is not specified, an early + # version of Envoy will be used. + imageConsul: null + imageEnvoy: null + # namespaceSelector is the selector for restricting the webhook to only # specific namespaces. This should be set to a multiline string. namespaceSelector: null From e19d61d462d3535f8544caf885d0a2d3a77788d7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Oct 2018 22:26:00 -0700 Subject: [PATCH 062/739] client: value for enabling gRPC --- templates/client-daemonset.yaml | 6 ++++++ test/unit/client-daemonset.yaml | 22 ++++++++++++++++++++++ values.yaml | 8 ++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 10a332cb1d..7ed213a713 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -71,6 +71,9 @@ spec: -advertise="${POD_IP}" \ -bind=0.0.0.0 \ -client=0.0.0.0 \ + {{- if .Values.client.grpc }} + -hcl="ports { grpc = 8502 }" \ + {{- end }} -config-dir=/consul/config \ {{- range .Values.client.extraVolumes }} {{- if .load }} @@ -112,6 +115,9 @@ spec: - containerPort: 8500 hostPort: 8500 name: http + - containerPort: 8502 + hostPort: 8502 + name: grpc - containerPort: 8301 name: serflan - containerPort: 8302 diff --git a/test/unit/client-daemonset.yaml b/test/unit/client-daemonset.yaml index bc50dc1cbf..2b9dbdc53e 100755 --- a/test/unit/client-daemonset.yaml +++ b/test/unit/client-daemonset.yaml @@ -72,6 +72,28 @@ load _helpers [ "${actual}" = "null" ] } +#-------------------------------------------------------------------- +# grpc + +@test "client/DaemonSet: grpc is disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("grpc"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: grpc can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("grpc"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # extraVolumes diff --git a/values.yaml b/values.yaml index d79d0f6d25..ad27b38be0 100644 --- a/values.yaml +++ b/values.yaml @@ -67,7 +67,7 @@ server: maxUnavailable: null # extraConfig is a raw string of extra configuration to set with the - # server. This should be JSON or HCL. + # server. This should be JSON. extraConfig: | {} @@ -87,13 +87,17 @@ client: image: null join: null + # grpc should be set to true if the gRPC listener should be enabled. + # This should be set to true if connectInject is enabled. + grpc: false + # Resource requests, limits, etc. for the client cluster placement. This # should map directly to the value of the resources field for a PodSpec. # By default no direct resource request is made. resources: {} # extraConfig is a raw string of extra configuration to set with the - # server. This should be JSON or HCL. + # server. This should be JSON. extraConfig: | {} From a887d7dfc85edeebb4f840ad1f5c83494fa0d397 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Oct 2018 22:27:07 -0700 Subject: [PATCH 063/739] syncCatalog: disable connect inject on deployment --- templates/sync-catalog-deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 937891d62a..500b24a0f3 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -24,6 +24,8 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: sync-catalog + annotations: + "consul.hashicorp.com/connect-inject": "false" spec: containers: - name: consul-sync-catalog From 983fb9a53b721a3c5e54e1690c388561f5a1cdcd Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Oct 2018 22:56:21 -0700 Subject: [PATCH 064/739] connectInject: use the correct subcommand --- templates/connect-inject-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index b760a3a6cc..cde5a9c13f 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -39,7 +39,7 @@ spec: - | CONSUL_FULLNAME="{{template "consul.fullname" . }}" - consul-k8s inject \ + consul-k8s inject-connect \ -default-inject={{ .Values.connectInject.default }} \ -consul-image="{{ default .Values.global.image .Values.connectInject.imageConsul }}" \ {{ if .Values.connectInject.imageEnvoy -}} From b0176f6b27bef2efb4ded4f0c9ed8d8e4d761d99 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 7 Oct 2018 23:28:21 -0700 Subject: [PATCH 065/739] remove unused values --- templates/connect-inject-mutatingwebhook.yaml | 2 +- values.yaml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 7d95357870..ec5e8ca95f 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -16,7 +16,7 @@ webhooks: name: {{ template "consul.fullname" . }}-connect-injector-svc namespace: default path: "/mutate" - caBundle: {{ .Values.connectInject.caBundle }} + caBundle: {{ .Values.connectInject.certs.caBundle }} rules: - operations: [ "CREATE" ] apiGroups: [""] diff --git a/values.yaml b/values.yaml index ad27b38be0..c58b2c8c84 100644 --- a/values.yaml +++ b/values.yaml @@ -160,9 +160,7 @@ syncCatalog: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false # "-" disable this by default for now until the image is public - image: null default: false # true will inject by default, otherwise requires annotation - caBundle: "" # empty will auto generate the bundle # imageConsul and imageEnvoy can be set to Docker images for Consul and # Envoy, respectively. If the Consul image is not specified, the global From 633089532db3d104cbe9dc7563976e81d14c49ea Mon Sep 17 00:00:00 2001 From: Tom Ganem Date: Tue, 9 Oct 2018 12:14:56 -0700 Subject: [PATCH 066/739] feat: add rbac support closes #20 --- templates/sync-cluster-role-binding.yaml | 21 +++++++++ templates/sync-cluster-role.yaml | 25 +++++++++++ test/unit/sync-cluster-role-binding.bats | 56 ++++++++++++++++++++++++ test/unit/sync-cluster-role.bats | 56 ++++++++++++++++++++++++ values.yaml | 5 +++ 5 files changed, 163 insertions(+) create mode 100644 templates/sync-cluster-role-binding.yaml create mode 100644 templates/sync-cluster-role.yaml create mode 100755 test/unit/sync-cluster-role-binding.bats create mode 100755 test/unit/sync-cluster-role.bats diff --git a/templates/sync-cluster-role-binding.yaml b/templates/sync-cluster-role-binding.yaml new file mode 100644 index 0000000000..77e84ca81e --- /dev/null +++ b/templates/sync-cluster-role-binding.yaml @@ -0,0 +1,21 @@ +{{- $rbacEnabled := (or (and (ne (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled) (and (eq (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled)) }} +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and $rbacEnabled $syncEnabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: consul:sync + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: consul:sync +subjects: + - kind: Group + name: system:serviceaccounts:{{ .Release.Namespace }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/templates/sync-cluster-role.yaml b/templates/sync-cluster-role.yaml new file mode 100644 index 0000000000..9252feaed9 --- /dev/null +++ b/templates/sync-cluster-role.yaml @@ -0,0 +1,25 @@ +{{- $rbacEnabled := (or (and (ne (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled) (and (eq (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled)) }} +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and $rbacEnabled $syncEnabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: consul:sync + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: + - apiGroups: [""] + resources: + - services + - endpoints + verbs: + - get + - list + - watch + - update + - patch + - delete +{{- end }} diff --git a/test/unit/sync-cluster-role-binding.bats b/test/unit/sync-cluster-role-binding.bats new file mode 100755 index 0000000000..4545ae535a --- /dev/null +++ b/test/unit/sync-cluster-role-binding.bats @@ -0,0 +1,56 @@ +#!/usr/bin/env bats + +load _helpers + +@test "sync/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role-binding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRoleBinding: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role-binding.yaml \ + --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ + --set 'rbac.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "sync/ClusterRoleBinding: disable with syncCatalog.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role-binding.yaml \ + --set 'syncCatalog.enabled=false' \ + --set 'rbac.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRoleBinding: disable with rbac.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role-binding.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'rbac.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRoleBinding: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role-binding.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/sync-cluster-role.bats b/test/unit/sync-cluster-role.bats new file mode 100755 index 0000000000..6fb9b1151d --- /dev/null +++ b/test/unit/sync-cluster-role.bats @@ -0,0 +1,56 @@ +#!/usr/bin/env bats + +load _helpers + +@test "sync/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRole: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role.yaml \ + --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ + --set 'rbac.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "sync/ClusterRole: disable with syncCatalog.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role.yaml \ + --set 'syncCatalog.enabled=false' \ + --set 'rbac.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRole: disable with rbac.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'rbac.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ClusterRole: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-cluster-role.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 83182d3adc..ec2a5ad37a 100644 --- a/values.yaml +++ b/values.yaml @@ -186,3 +186,8 @@ connectInject: # defaults but can be customized if necessary. certName: tls.crt keyName: tls.key + +# Enabling rbac will create cluster roles and cluster role bindings to allow the +# syncCatalog service to communicate with the kubernetes api to get/create services +rbac: + enabled: false From 345fbbc472a2d50ec871b2816bc9ebeeb98bc280 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 10 Oct 2018 08:19:02 -0700 Subject: [PATCH 067/739] update values --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index c58b2c8c84..710d373c36 100644 --- a/values.yaml +++ b/values.yaml @@ -159,7 +159,7 @@ syncCatalog: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: - enabled: false # "-" disable this by default for now until the image is public + enabled: false default: false # true will inject by default, otherwise requires annotation # imageConsul and imageEnvoy can be set to Docker images for Consul and From 4edc54adb387428e93211836c4fd49880425a82c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 10 Oct 2018 08:23:32 -0700 Subject: [PATCH 068/739] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c769c023b..8b9a632523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## UNRELEASED + +FEATURES: + + * `connectInject` can install the automatic Connect sidecar injector. + ## 0.2.0 (September 26, 2018) FEATURES: From 36ab9d08b551a66be1191cec5aad34eb92da5277 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 10 Oct 2018 09:52:16 -0700 Subject: [PATCH 069/739] connectInject: need image, add tests --- test/unit/connect-inject-deployment.bats | 23 +++++++++++++++++++++++ values.yaml | 1 + 2 files changed, 24 insertions(+) diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 18a02a5b3d..a3a0104c6d 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -45,6 +45,29 @@ load _helpers #-------------------------------------------------------------------- # consul and envoy images +@test "connectInject/Deployment: container image is global default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.imageK8S=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "\"foo\"" ] +} + +@test "connectInject/Deployment: container image overrides" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.imageK8S=foo' \ + --set 'connectInject.image=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "\"bar\"" ] +} + @test "connectInject/Deployment: consul-image defaults to global" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index 710d373c36..7121f126b8 100644 --- a/values.yaml +++ b/values.yaml @@ -160,6 +160,7 @@ syncCatalog: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false + image: null # image for consul-k8s that contains the injector default: false # true will inject by default, otherwise requires annotation # imageConsul and imageEnvoy can be set to Docker images for Consul and From cd180898555042678cd54f273db57bb458d8a746 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 11 Oct 2018 11:36:34 -0700 Subject: [PATCH 070/739] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b9a632523..723a5127d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## UNRELEASED +## 0.3.0 (October 11, 2018) FEATURES: From 516d510aca5ed8f15ab42eebc9fe32add799cc2b Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Fri, 12 Oct 2018 09:10:49 -0700 Subject: [PATCH 071/739] updating docker images to the latest version --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 7121f126b8..71596a9f67 100644 --- a/values.yaml +++ b/values.yaml @@ -16,12 +16,12 @@ global: # Image is the name (and tag) of the Consul Docker image for clients and # servers below. This can be overridden per component. - image: "consul:1.2.3" + image: "consul:1.3.0" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.1.0" + imageK8S: "hashicorp/consul-k8s:0.2.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From cf5cf1e7748a6e9ac41c7a30117d7ab7bb568946 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 12 Oct 2018 09:18:27 -0700 Subject: [PATCH 072/739] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 723a5127d1..68e9ebf999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## UNRELEASED + +BUG FIXES: + + * Updated images to point to latest versions for 0.3.0. + ## 0.3.0 (October 11, 2018) FEATURES: From 76da392dbab8ee2856df300a741e1f0c205ee380 Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Sun, 14 Oct 2018 18:46:49 -0700 Subject: [PATCH 073/739] connectInject: use service account to auto-generate certs --- templates/connect-inject-clusterrole.yaml | 16 ++++++++++++++++ .../connect-inject-clusterrolebinding.yaml | 19 +++++++++++++++++++ templates/connect-inject-deployment.yaml | 5 ++++- templates/connect-inject-serviceaccount.yaml | 12 ++++++++++++ values.yaml | 3 ++- 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 templates/connect-inject-clusterrole.yaml create mode 100644 templates/connect-inject-clusterrolebinding.yaml create mode 100644 templates/connect-inject-serviceaccount.yaml diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml new file mode 100644 index 0000000000..dd0a49e16c --- /dev/null +++ b/templates/connect-inject-clusterrole.yaml @@ -0,0 +1,16 @@ +# The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration. +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-webhook + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations"] + verbs: ["get", "list", "watch", "patch"] +{{- end }} diff --git a/templates/connect-inject-clusterrolebinding.yaml b/templates/connect-inject-clusterrolebinding.yaml new file mode 100644 index 0000000000..12aaf36161 --- /dev/null +++ b/templates/connect-inject-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: connect-injector-webhook-admin-role-binding-{{ template "consul.fullname" . }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-connect-injector-webhook +subjects: + - kind: ServiceAccount + name: connect-injector-webhook-service-account + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index cde5a9c13f..241944e8de 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -25,6 +25,9 @@ spec: release: {{ .Release.Name }} component: connect-injector spec: + {{- if not .Values.connectInject.certs.secretName }} + serviceAccountName: connect-injector-webhook-service-account + {{- end }} containers: - name: sidecar-injector image: "{{ default .Values.global.imageK8S .Values.connectInject.image }}" @@ -50,7 +53,7 @@ spec: -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} {{- else }} - -tls-auto=consul-connect-injector-cfg \ + -tls-auto={{ template "consul.fullname" . }}-connect-injector-cfg \ -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc {{- end }} livenessProbe: diff --git a/templates/connect-inject-serviceaccount.yaml b/templates/connect-inject-serviceaccount.yaml new file mode 100644 index 0000000000..eeecb6932d --- /dev/null +++ b/templates/connect-inject-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: connect-injector-webhook-service-account + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} \ No newline at end of file diff --git a/values.yaml b/values.yaml index 71596a9f67..b136b04034 100644 --- a/values.yaml +++ b/values.yaml @@ -183,7 +183,8 @@ connectInject: certs: # secretName is the name of the secret that has the TLS certificate and # private key to serve the injector webhook. If this is null, then the - # injector will default to its automatic management mode. + # injector will default to its automatic management mode that will assign + # a service account to the injector to generate its own certificates. secretName: null # caBundle is a base64-encoded PEM-encoded certificate bundle for the From 202e4d8f046eb4c9659f81bf5f480139d5004b5c Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Sun, 14 Oct 2018 18:48:42 -0700 Subject: [PATCH 074/739] add a few newlines --- templates/connect-inject-clusterrolebinding.yaml | 2 +- templates/connect-inject-serviceaccount.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/connect-inject-clusterrolebinding.yaml b/templates/connect-inject-clusterrolebinding.yaml index 12aaf36161..70ff7224eb 100644 --- a/templates/connect-inject-clusterrolebinding.yaml +++ b/templates/connect-inject-clusterrolebinding.yaml @@ -16,4 +16,4 @@ subjects: - kind: ServiceAccount name: connect-injector-webhook-service-account namespace: {{ .Release.Namespace }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/templates/connect-inject-serviceaccount.yaml b/templates/connect-inject-serviceaccount.yaml index eeecb6932d..adf4f846e4 100644 --- a/templates/connect-inject-serviceaccount.yaml +++ b/templates/connect-inject-serviceaccount.yaml @@ -9,4 +9,4 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- end }} \ No newline at end of file +{{- end }} From 32ed79e96ac96f5b3e899b5cfa3d30644817f39a Mon Sep 17 00:00:00 2001 From: Tom Ganem Date: Mon, 15 Oct 2018 13:58:32 -0700 Subject: [PATCH 075/739] fix: move .Values.rbac.enabled to .Values.syncCatalog.rbac.enabled --- templates/sync-cluster-role-binding.yaml | 2 +- templates/sync-cluster-role.yaml | 2 +- test/unit/sync-cluster-role-binding.bats | 9 +++++---- test/unit/sync-cluster-role.bats | 7 ++++--- values.yaml | 9 ++++----- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/templates/sync-cluster-role-binding.yaml b/templates/sync-cluster-role-binding.yaml index 77e84ca81e..a7787f23da 100644 --- a/templates/sync-cluster-role-binding.yaml +++ b/templates/sync-cluster-role-binding.yaml @@ -1,4 +1,4 @@ -{{- $rbacEnabled := (or (and (ne (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled) (and (eq (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled)) }} +{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and $rbacEnabled $syncEnabled) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/sync-cluster-role.yaml b/templates/sync-cluster-role.yaml index 9252feaed9..18ef732dcf 100644 --- a/templates/sync-cluster-role.yaml +++ b/templates/sync-cluster-role.yaml @@ -1,4 +1,4 @@ -{{- $rbacEnabled := (or (and (ne (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled) (and (eq (.Values.rbac.enabled | toString) "-") .Values.rbac.enabled)) }} +{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and $rbacEnabled $syncEnabled) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/test/unit/sync-cluster-role-binding.bats b/test/unit/sync-cluster-role-binding.bats index 4545ae535a..ee64a38289 100755 --- a/test/unit/sync-cluster-role-binding.bats +++ b/test/unit/sync-cluster-role-binding.bats @@ -17,7 +17,7 @@ load _helpers -x templates/sync-cluster-role-binding.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ - --set 'rbac.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -28,18 +28,18 @@ load _helpers local actual=$(helm template \ -x templates/sync-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=false' \ - --set 'rbac.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: disable with rbac.enabled" { +@test "sync/ClusterRoleBinding: disable with syncCatalog.rbac.enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'rbac.enabled=false' \ + --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -49,6 +49,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/sync-cluster-role-binding.yaml \ + --set 'syncCatalog.rbac.enabled="-"' \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/sync-cluster-role.bats b/test/unit/sync-cluster-role.bats index 6fb9b1151d..4a6ba74bd9 100755 --- a/test/unit/sync-cluster-role.bats +++ b/test/unit/sync-cluster-role.bats @@ -17,7 +17,7 @@ load _helpers -x templates/sync-cluster-role.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ - --set 'rbac.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -28,7 +28,7 @@ load _helpers local actual=$(helm template \ -x templates/sync-cluster-role.yaml \ --set 'syncCatalog.enabled=false' \ - --set 'rbac.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -39,7 +39,7 @@ load _helpers local actual=$(helm template \ -x templates/sync-cluster-role.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'rbac.enabled=false' \ + --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -50,6 +50,7 @@ load _helpers local actual=$(helm template \ -x templates/sync-cluster-role.yaml \ --set 'global.enabled=false' \ + --set 'syncCatalog.rbac.enabled="-"' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] diff --git a/values.yaml b/values.yaml index ec2a5ad37a..eecb72594c 100644 --- a/values.yaml +++ b/values.yaml @@ -142,6 +142,10 @@ syncCatalog: # True if you want to enable the catalog sync. "-" for default. enabled: false image: null + # Enabling rbac will create cluster roles and cluster role bindings to allow the + # syncCatalog service to communicate with the kubernetes api to get/create services + rbac: + enabled: false # toConsul and toK8S control whether syncing is enabled to Consul or K8S # as a destination. If both of these are disabled, the sync will do nothing. @@ -186,8 +190,3 @@ connectInject: # defaults but can be customized if necessary. certName: tls.crt keyName: tls.key - -# Enabling rbac will create cluster roles and cluster role bindings to allow the -# syncCatalog service to communicate with the kubernetes api to get/create services -rbac: - enabled: false From 6d9c8847a539a6b0ba0bcc1bc2c33ca1872c5677 Mon Sep 17 00:00:00 2001 From: Tom Ganem Date: Mon, 15 Oct 2018 13:59:25 -0700 Subject: [PATCH 076/739] feat: create serviceAccount for sync catalog cluster role bind --- templates/sync-catalog-deployment.yaml | 4 ++ templates/sync-cluster-role-binding.yaml | 10 ++--- templates/sync-cluster-role.yaml | 2 +- templates/sync-service-account.yaml | 14 ++++++ test/unit/sync-catalog-deployment.bats | 14 ++++++ test/unit/sync-service-account.bats | 57 ++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 templates/sync-service-account.yaml create mode 100755 test/unit/sync-service-account.bats diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 937891d62a..674d0d8e6b 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -1,4 +1,5 @@ # The deployment for running the Connect sidecar injector +{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: apps/v1 kind: Deployment @@ -25,6 +26,9 @@ spec: release: {{ .Release.Name }} component: sync-catalog spec: + {{- if $rbacEnabled }} + serviceAccountName: {{ template "consul.fullname" . }}:sync-catalog + {{- end }} containers: - name: consul-sync-catalog image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" diff --git a/templates/sync-cluster-role-binding.yaml b/templates/sync-cluster-role-binding.yaml index a7787f23da..2c7950f758 100644 --- a/templates/sync-cluster-role-binding.yaml +++ b/templates/sync-cluster-role-binding.yaml @@ -4,7 +4,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: consul:sync + name: {{ template "consul.fullname" . }}:sync-catalog labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -13,9 +13,9 @@ metadata: roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: consul:sync + name: {{ template "consul.fullname" . }}:sync-catalog subjects: - - kind: Group - name: system:serviceaccounts:{{ .Release.Namespace }} - apiGroup: rbac.authorization.k8s.io + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}:sync-catalog + namespace: {{ .Release.Namespace }} {{- end }} diff --git a/templates/sync-cluster-role.yaml b/templates/sync-cluster-role.yaml index 18ef732dcf..2458bfff10 100644 --- a/templates/sync-cluster-role.yaml +++ b/templates/sync-cluster-role.yaml @@ -4,7 +4,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: consul:sync + name: {{ template "consul.fullname" . }}:sync-catalog labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/sync-service-account.yaml b/templates/sync-service-account.yaml new file mode 100644 index 0000000000..3b3905395f --- /dev/null +++ b/templates/sync-service-account.yaml @@ -0,0 +1,14 @@ +{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and $rbacEnabled $syncEnabled) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}:sync-catalog + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index c9f0f30bd2..c7079e60c6 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -149,3 +149,17 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-k8s-service-prefix=\"foo-\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# serviceAccount + +@test "syncCatalog/Deployment: serviceAccount set with rbac.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.serviceAccountName | contains("sync-catalog")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/sync-service-account.bats b/test/unit/sync-service-account.bats new file mode 100755 index 0000000000..00ed9327b2 --- /dev/null +++ b/test/unit/sync-service-account.bats @@ -0,0 +1,57 @@ +#!/usr/bin/env bats + +load _helpers + +@test "sync/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-service-account.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ServiceAccount: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-service-account.yaml \ + --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.rbac.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "sync/ServiceAccount: disable with syncCatalog.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-service-account.yaml \ + --set 'syncCatalog.enabled=false' \ + --set 'syncCatalog.rbac.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ServiceAccount: disable with syncCatalog.rbac.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-service-account.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.rbac.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "sync/ServiceAccount: disable with global.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-service-account.yaml \ + --set 'syncCatalog.rbac.enabled="-"' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} From 69c275146dff16f5821e0cd36459807f1f9ea5a7 Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Tue, 16 Oct 2018 10:08:09 -0700 Subject: [PATCH 077/739] Fix connect inject configuration name Doing this PR separately to fix #36 since it is independent of my [PR](https://github.com/hashicorp/consul-helm/pull/37) for RBAC for the injector. --- templates/connect-inject-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index cde5a9c13f..59420819c1 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -50,7 +50,7 @@ spec: -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} {{- else }} - -tls-auto=consul-connect-injector-cfg \ + -tls-auto={{ template "consul.fullname" . }}-connect-injector-cfg \ -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc {{- end }} livenessProbe: From e02986b980c874a7e5fffb36fc9edecafed2463c Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Tue, 16 Oct 2018 14:37:12 -0700 Subject: [PATCH 078/739] Update connect-inject-deployment.yaml --- templates/connect-inject-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 59420819c1..250a2f2a4f 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -50,7 +50,7 @@ spec: -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} {{- else }} - -tls-auto={{ template "consul.fullname" . }}-connect-injector-cfg \ + -tls-auto=${CONSUL_FULLNAME}-connect-injector-cfg \ -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc {{- end }} livenessProbe: From 4f87c89834d1872f82ade3772495cc5962df100a Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 16 Oct 2018 16:01:24 -0700 Subject: [PATCH 079/739] Add command continue indications where needed --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 7ed213a713..1ef9591ebb 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -77,7 +77,7 @@ spec: -config-dir=/consul/config \ {{- range .Values.client.extraVolumes }} {{- if .load }} - -config-dir=/consul/userconfig/{{ .name }} + -config-dir=/consul/userconfig/{{ .name }} \ {{- end }} {{- end }} -datacenter={{ .Values.global.datacenter }} \ diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index cd9e008459..f1cf791636 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -88,7 +88,7 @@ spec: -config-dir=/consul/config \ {{- range .Values.server.extraVolumes }} {{- if .load }} - -config-dir=/consul/userconfig/{{ .name }} + -config-dir=/consul/userconfig/{{ .name }} \ {{- end }} {{- end }} -datacenter={{ .Values.global.datacenter }} \ From 701313f25d27946b83535b3f3d3de9c9329d7d70 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 16 Oct 2018 17:12:44 -0700 Subject: [PATCH 080/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e9ebf999..a919422dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ BUG FIXES: * Updated images to point to latest versions for 0.3.0. + * Add missing continuation characters to long commands [GH-26]. ## 0.3.0 (October 11, 2018) From e30272e4aa8a401f30f9e076007619e86164a80f Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Tue, 16 Oct 2018 23:14:09 -0700 Subject: [PATCH 081/739] connectInject: adding tests, unique service account name per helm install --- templates/connect-inject-deployment.yaml | 2 +- templates/connect-inject-serviceaccount.yaml | 2 +- test/unit/connect-inject-clusterrole.bats | 53 +++++++++++++++++++ .../connect-inject-clusterrolebinding.bats | 53 +++++++++++++++++++ test/unit/connect-inject-deployment.bats | 25 +++++++++ test/unit/connect-inject-serviceaccount.bats | 53 +++++++++++++++++++ 6 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 test/unit/connect-inject-clusterrole.bats create mode 100644 test/unit/connect-inject-clusterrolebinding.bats create mode 100644 test/unit/connect-inject-serviceaccount.bats diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 494375a2f0..cfab92b304 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -26,7 +26,7 @@ spec: component: connect-injector spec: {{- if not .Values.connectInject.certs.secretName }} - serviceAccountName: connect-injector-webhook-service-account + serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account {{- end }} containers: - name: sidecar-injector diff --git a/templates/connect-inject-serviceaccount.yaml b/templates/connect-inject-serviceaccount.yaml index adf4f846e4..2bb0919f07 100644 --- a/templates/connect-inject-serviceaccount.yaml +++ b/templates/connect-inject-serviceaccount.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: connect-injector-webhook-service-account + name: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats new file mode 100644 index 0000000000..77ca662342 --- /dev/null +++ b/test/unit/connect-inject-clusterrole.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers +@test "connectInject/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRole: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/ClusterRole: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRole: disable with connectInject.certs.secretName set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=false' \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRole: enable with connectInject.certs.secretName not set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-clusterrolebinding.bats b/test/unit/connect-inject-clusterrolebinding.bats new file mode 100644 index 0000000000..0ff17a9e28 --- /dev/null +++ b/test/unit/connect-inject-clusterrolebinding.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers +@test "connectInject/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRoleBinding: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/ClusterRoleBinding: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrolebinding.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRoleBinding: disable with connectInject.certs.secretName set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrolebinding.yaml \ + --set 'connectInject.enabled=false' \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ClusterRoleBinding: enable with connectInject.certs.secretName not set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrolebinding.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index a3a0104c6d..fec7d18ac3 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -165,3 +165,28 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-tls-auto"))' | tee /dev/stderr) [ "${actual}" = "false" ] } + + +#-------------------------------------------------------------------- +# service account name + +@test "connectInject/Deployment: with secretName: no serviceAccountName set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.certs.secretName=foo' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.serviceAccountName | has("serviceAccountName")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: no secretName: serviceAccountName set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.serviceAccountName | contains("connect-injector-webhook-svc-account")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/test/unit/connect-inject-serviceaccount.bats b/test/unit/connect-inject-serviceaccount.bats new file mode 100644 index 0000000000..7b73120c8c --- /dev/null +++ b/test/unit/connect-inject-serviceaccount.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers +@test "connectInject/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ServiceAccount: enable with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/ServiceAccount: disable with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + --set 'connectInject.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ServiceAccount: disable with connectInject.certs.secretName set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + --set 'connectInject.enabled=false' \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/ServiceAccount: enable with connectInject.certs.secretName not set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From 2403d410f99b648595ad49827894b0f8379c7711 Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Tue, 16 Oct 2018 23:29:56 -0700 Subject: [PATCH 082/739] namespace is now set using helm release --- templates/connect-inject-mutatingwebhook.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index ec5e8ca95f..47e6b80023 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -14,7 +14,7 @@ webhooks: clientConfig: service: name: {{ template "consul.fullname" . }}-connect-injector-svc - namespace: default + namespace: {{ .Release.Namespace }} path: "/mutate" caBundle: {{ .Values.connectInject.certs.caBundle }} rules: From 973cc2e4a4ae71de83eed7f552c7507e22f5e0a8 Mon Sep 17 00:00:00 2001 From: Tom Ganem Date: Wed, 17 Oct 2018 12:24:48 -0700 Subject: [PATCH 083/739] fix: use a "-" instead of a ":" for names --- templates/sync-catalog-deployment.yaml | 2 +- templates/sync-cluster-role-binding.yaml | 6 +++--- templates/sync-cluster-role.yaml | 2 +- templates/sync-service-account.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 674d0d8e6b..342d3ce8e6 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -27,7 +27,7 @@ spec: component: sync-catalog spec: {{- if $rbacEnabled }} - serviceAccountName: {{ template "consul.fullname" . }}:sync-catalog + serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog {{- end }} containers: - name: consul-sync-catalog diff --git a/templates/sync-cluster-role-binding.yaml b/templates/sync-cluster-role-binding.yaml index 2c7950f758..431ef05e7a 100644 --- a/templates/sync-cluster-role-binding.yaml +++ b/templates/sync-cluster-role-binding.yaml @@ -4,7 +4,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: {{ template "consul.fullname" . }}:sync-catalog + name: {{ template "consul.fullname" . }}-sync-catalog labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -13,9 +13,9 @@ metadata: roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: {{ template "consul.fullname" . }}:sync-catalog + name: {{ template "consul.fullname" . }}-sync-catalog subjects: - kind: ServiceAccount - name: {{ template "consul.fullname" . }}:sync-catalog + name: {{ template "consul.fullname" . }}-sync-catalog namespace: {{ .Release.Namespace }} {{- end }} diff --git a/templates/sync-cluster-role.yaml b/templates/sync-cluster-role.yaml index 2458bfff10..9c7b3c7d35 100644 --- a/templates/sync-cluster-role.yaml +++ b/templates/sync-cluster-role.yaml @@ -4,7 +4,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: {{ template "consul.fullname" . }}:sync-catalog + name: {{ template "consul.fullname" . }}-sync-catalog labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/sync-service-account.yaml b/templates/sync-service-account.yaml index 3b3905395f..b8d997172f 100644 --- a/templates/sync-service-account.yaml +++ b/templates/sync-service-account.yaml @@ -4,7 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{ template "consul.fullname" . }}:sync-catalog + name: {{ template "consul.fullname" . }}-sync-catalog namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} From 97b0f12bbf31054f176857b8ffaef8828c6df697 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Oct 2018 08:59:28 -0700 Subject: [PATCH 084/739] Rename files, add create to role --- ...ing.yaml => sync-catalog-cluster-role-binding.yaml} | 0 ...luster-role.yaml => sync-catalog-cluster-role.yaml} | 1 + ...-account.yaml => sync-catalog-service-account.yaml} | 0 ...ing.bats => sync-catalog-cluster-role-binding.bats} | 10 +++++----- ...luster-role.bats => sync-catalog-cluster-role.bats} | 10 +++++----- test/unit/sync-service-account.bats | 10 +++++----- values.yaml | 8 +++++--- 7 files changed, 21 insertions(+), 18 deletions(-) rename templates/{sync-cluster-role-binding.yaml => sync-catalog-cluster-role-binding.yaml} (100%) rename templates/{sync-cluster-role.yaml => sync-catalog-cluster-role.yaml} (98%) rename templates/{sync-service-account.yaml => sync-catalog-service-account.yaml} (100%) rename test/unit/{sync-cluster-role-binding.bats => sync-catalog-cluster-role-binding.bats} (83%) rename test/unit/{sync-cluster-role.bats => sync-catalog-cluster-role.bats} (84%) diff --git a/templates/sync-cluster-role-binding.yaml b/templates/sync-catalog-cluster-role-binding.yaml similarity index 100% rename from templates/sync-cluster-role-binding.yaml rename to templates/sync-catalog-cluster-role-binding.yaml diff --git a/templates/sync-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml similarity index 98% rename from templates/sync-cluster-role.yaml rename to templates/sync-catalog-cluster-role.yaml index 9c7b3c7d35..4dc398f0ab 100644 --- a/templates/sync-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -22,4 +22,5 @@ rules: - update - patch - delete + - create {{- end }} diff --git a/templates/sync-service-account.yaml b/templates/sync-catalog-service-account.yaml similarity index 100% rename from templates/sync-service-account.yaml rename to templates/sync-catalog-service-account.yaml diff --git a/test/unit/sync-cluster-role-binding.bats b/test/unit/sync-catalog-cluster-role-binding.bats similarity index 83% rename from test/unit/sync-cluster-role-binding.bats rename to test/unit/sync-catalog-cluster-role-binding.bats index ee64a38289..21e80e4973 100755 --- a/test/unit/sync-cluster-role-binding.bats +++ b/test/unit/sync-catalog-cluster-role-binding.bats @@ -5,7 +5,7 @@ load _helpers @test "sync/ClusterRoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role-binding.yaml \ + -x templates/sync-catalog-cluster-role-binding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -14,7 +14,7 @@ load _helpers @test "sync/ClusterRoleBinding: enable with global.enabled false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role-binding.yaml \ + -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=true' \ @@ -26,7 +26,7 @@ load _helpers @test "sync/ClusterRoleBinding: disable with syncCatalog.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role-binding.yaml \ + -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=false' \ --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | @@ -37,7 +37,7 @@ load _helpers @test "sync/ClusterRoleBinding: disable with syncCatalog.rbac.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role-binding.yaml \ + -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | @@ -48,7 +48,7 @@ load _helpers @test "sync/ClusterRoleBinding: disable with global.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role-binding.yaml \ + -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'syncCatalog.rbac.enabled="-"' \ --set 'global.enabled=false' \ . | tee /dev/stderr | diff --git a/test/unit/sync-cluster-role.bats b/test/unit/sync-catalog-cluster-role.bats similarity index 84% rename from test/unit/sync-cluster-role.bats rename to test/unit/sync-catalog-cluster-role.bats index 4a6ba74bd9..3e08bad568 100755 --- a/test/unit/sync-cluster-role.bats +++ b/test/unit/sync-catalog-cluster-role.bats @@ -5,7 +5,7 @@ load _helpers @test "sync/ClusterRole: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role.yaml \ + -x templates/sync-catalog-cluster-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -14,7 +14,7 @@ load _helpers @test "sync/ClusterRole: enable with global.enabled false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role.yaml \ + -x templates/sync-catalog-cluster-role.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=true' \ @@ -26,7 +26,7 @@ load _helpers @test "sync/ClusterRole: disable with syncCatalog.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role.yaml \ + -x templates/sync-catalog-cluster-role.yaml \ --set 'syncCatalog.enabled=false' \ --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | @@ -37,7 +37,7 @@ load _helpers @test "sync/ClusterRole: disable with rbac.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role.yaml \ + -x templates/sync-catalog-cluster-role.yaml \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | @@ -48,7 +48,7 @@ load _helpers @test "sync/ClusterRole: disable with global.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-cluster-role.yaml \ + -x templates/sync-catalog-cluster-role.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.rbac.enabled="-"' \ . | tee /dev/stderr | diff --git a/test/unit/sync-service-account.bats b/test/unit/sync-service-account.bats index 00ed9327b2..5a49d5cc8e 100755 --- a/test/unit/sync-service-account.bats +++ b/test/unit/sync-service-account.bats @@ -5,7 +5,7 @@ load _helpers @test "sync/ServiceAccount: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-service-account.yaml \ + -x templates/sync-catalog-service-account.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -14,7 +14,7 @@ load _helpers @test "sync/ServiceAccount: enable with global.enabled false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-service-account.yaml \ + -x templates/sync-catalog-service-account.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=true' \ @@ -26,7 +26,7 @@ load _helpers @test "sync/ServiceAccount: disable with syncCatalog.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-service-account.yaml \ + -x templates/sync-catalog-service-account.yaml \ --set 'syncCatalog.enabled=false' \ --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | @@ -37,7 +37,7 @@ load _helpers @test "sync/ServiceAccount: disable with syncCatalog.rbac.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-service-account.yaml \ + -x templates/sync-catalog-service-account.yaml \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | @@ -48,7 +48,7 @@ load _helpers @test "sync/ServiceAccount: disable with global.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-service-account.yaml \ + -x templates/sync-catalog-service-account.yaml \ --set 'syncCatalog.rbac.enabled="-"' \ --set 'global.enabled=false' \ . | tee /dev/stderr | diff --git a/values.yaml b/values.yaml index 3b4c23994f..f9935e1c04 100644 --- a/values.yaml +++ b/values.yaml @@ -146,10 +146,12 @@ syncCatalog: # True if you want to enable the catalog sync. "-" for default. enabled: false image: null - # Enabling rbac will create cluster roles and cluster role bindings to allow the - # syncCatalog service to communicate with the kubernetes api to get/create services + + # Enabling rbac will create cluster roles and cluster role bindings to + # allow the syncCatalog service to communicate with the kubernetes api + # to get/create services. rbac: - enabled: false + enabled: true # toConsul and toK8S control whether syncing is enabled to Consul or K8S # as a destination. If both of these are disabled, the sync will do nothing. From dca609b98e57c50ca63b6164d8d6a44c9092c919 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Oct 2018 09:03:20 -0700 Subject: [PATCH 085/739] update CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a919422dd5..543ae2753f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## UNRELEASED +IMPROVEMENTS: + + * RBAC support for `syncCatalog`. This is enabled by default if the catalog + sync is enabled but can be controlled with `syncCatalog.rbac.enabled`. + This will create the `ClusterRole` and `ClusterRoleBinding` necessary + for the catalog sync. [GH-29] + BUG FIXES: * Updated images to point to latest versions for 0.3.0. From 14ec8eb6f2f27efbba9ad9004f122d388757bd3f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Oct 2018 15:36:04 -0700 Subject: [PATCH 086/739] add test for mutatingwebhook namespace --- test/unit/connect-inject-mutatingwebhook.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/unit/connect-inject-mutatingwebhook.yaml b/test/unit/connect-inject-mutatingwebhook.yaml index 1e2142c506..dd06f9cb9a 100755 --- a/test/unit/connect-inject-mutatingwebhook.yaml +++ b/test/unit/connect-inject-mutatingwebhook.yaml @@ -41,3 +41,14 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +@test "connectInject/MutatingWebhookConfiguration: namespace is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-mutatingwebhook.yaml \ + --set 'connectInject.enabled=true' \ + --namespace foo \ + . | tee /dev/stderr | + yq '.webhooks[0].clientConfig.service.namespace' | tee /dev/stderr) + [ "${actual}" = "\"foo\"" ] +} From e3dd9d318ffb013d1f87335a8adb89c395d39082 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Oct 2018 15:36:53 -0700 Subject: [PATCH 087/739] update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 543ae2753f..188b7479a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ BUG FIXES: * Updated images to point to latest versions for 0.3.0. * Add missing continuation characters to long commands [GH-26]. + * connectInject: set the correct namespace for the MutatingWebhookConfiguration + so that deployments work in non-default namespaces. [GH-41] ## 0.3.0 (October 11, 2018) From 386443a6e3c02570f760d427531b12688048fd1b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Oct 2018 22:17:28 -0700 Subject: [PATCH 088/739] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 188b7479a4..f76574bd14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ IMPROVEMENTS: sync is enabled but can be controlled with `syncCatalog.rbac.enabled`. This will create the `ClusterRole` and `ClusterRoleBinding` necessary for the catalog sync. [GH-29] + * client: agents now have the node name set to the actual K8S node name [GH-14] BUG FIXES: From 5c723250325a5f4a523467daa3c997ae725923ba Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Fri, 19 Oct 2018 09:20:47 -0700 Subject: [PATCH 089/739] addressing feedback from review --- templates/connect-inject-clusterrolebinding.yaml | 4 ++-- test/unit/connect-inject-clusterrole.bats | 10 +++++----- test/unit/connect-inject-clusterrolebinding.bats | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/templates/connect-inject-clusterrolebinding.yaml b/templates/connect-inject-clusterrolebinding.yaml index 70ff7224eb..0da9587e0c 100644 --- a/templates/connect-inject-clusterrolebinding.yaml +++ b/templates/connect-inject-clusterrolebinding.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: - name: connect-injector-webhook-admin-role-binding-{{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-connect-injector-webhook-admin-role-binding labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -14,6 +14,6 @@ roleRef: name: {{ template "consul.fullname" . }}-connect-injector-webhook subjects: - kind: ServiceAccount - name: connect-injector-webhook-service-account + name: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account namespace: {{ .Release.Namespace }} {{- end }} diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats index 77ca662342..cb282edd92 100644 --- a/test/unit/connect-inject-clusterrole.bats +++ b/test/unit/connect-inject-clusterrole.bats @@ -10,7 +10,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ClusterRole: enable with global.enabled false" { +@test "connectInject/ClusterRole: enabled with global.enabled false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ @@ -21,7 +21,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/ClusterRole: disable with connectInject.enabled" { +@test "connectInject/ClusterRole: disabled with connectInject.enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ @@ -31,18 +31,18 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ClusterRole: disable with connectInject.certs.secretName set" { +@test "connectInject/ClusterRole: disabled with connectInject.certs.secretName set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ - --set 'connectInject.enabled=false' \ + --set 'connectInject.enabled=true' \ --set 'connectInject.certs.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "connectInject/ClusterRole: enable with connectInject.certs.secretName not set" { +@test "connectInject/ClusterRole: enabled with connectInject.certs.secretName not set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ diff --git a/test/unit/connect-inject-clusterrolebinding.bats b/test/unit/connect-inject-clusterrolebinding.bats index 0ff17a9e28..a9a57108cd 100644 --- a/test/unit/connect-inject-clusterrolebinding.bats +++ b/test/unit/connect-inject-clusterrolebinding.bats @@ -10,7 +10,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ClusterRoleBinding: enable with global.enabled false" { +@test "connectInject/ClusterRoleBinding: enabled with global.enabled false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrolebinding.yaml \ @@ -21,7 +21,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/ClusterRoleBinding: disable with connectInject.enabled" { +@test "connectInject/ClusterRoleBinding: disabled with connectInject.enabled false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrolebinding.yaml \ @@ -31,18 +31,18 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ClusterRoleBinding: disable with connectInject.certs.secretName set" { +@test "connectInject/ClusterRoleBinding: disabled with connectInject.certs.secretName set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrolebinding.yaml \ - --set 'connectInject.enabled=false' \ + --set 'connectInject.enabled=true' \ --set 'connectInject.certs.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "connectInject/ClusterRoleBinding: enable with connectInject.certs.secretName not set" { +@test "connectInject/ClusterRoleBinding: enabled with connectInject.certs.secretName not set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrolebinding.yaml \ From f8dc314978f2ed1722ede0d73e75e115f294c4f1 Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Fri, 19 Oct 2018 09:24:21 -0700 Subject: [PATCH 090/739] making serviceaccount consistent with other tests --- templates/connect-inject-clusterrole.yaml | 6 +++++- test/unit/connect-inject-serviceaccount.bats | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index dd0a49e16c..a873c680db 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -12,5 +12,9 @@ metadata: rules: - apiGroups: ["admissionregistration.k8s.io"] resources: ["mutatingwebhookconfigurations"] - verbs: ["get", "list", "watch", "patch"] + verbs: + - "get" + - "list" + - "watch" + - "patch" {{- end }} diff --git a/test/unit/connect-inject-serviceaccount.bats b/test/unit/connect-inject-serviceaccount.bats index 7b73120c8c..1fc77be8ab 100644 --- a/test/unit/connect-inject-serviceaccount.bats +++ b/test/unit/connect-inject-serviceaccount.bats @@ -10,7 +10,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ServiceAccount: enable with global.enabled false" { +@test "connectInject/ServiceAccount: enabled with global.enabled false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-serviceaccount.yaml \ @@ -21,7 +21,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/ServiceAccount: disable with connectInject.enabled" { +@test "connectInject/ServiceAccount: disabled with connectInject.enabled false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-serviceaccount.yaml \ @@ -31,18 +31,18 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/ServiceAccount: disable with connectInject.certs.secretName set" { +@test "connectInject/ServiceAccount: disabled with connectInject.certs.secretName set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-serviceaccount.yaml \ - --set 'connectInject.enabled=false' \ + --set 'connectInject.enabled=true' \ --set 'connectInject.certs.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "connectInject/ServiceAccount: enable with connectInject.certs.secretName not set" { +@test "connectInject/ServiceAccount: enabled with connectInject.certs.secretName not set" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-serviceaccount.yaml \ From 789fdbc934b8ca37406da3ade39af8cd63821f73 Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Fri, 19 Oct 2018 15:23:00 -0700 Subject: [PATCH 091/739] update CHANGELOG to show connect injector RBAC support --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f76574bd14..2bc46579a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ IMPROVEMENTS: This will create the `ClusterRole` and `ClusterRoleBinding` necessary for the catalog sync. [GH-29] * client: agents now have the node name set to the actual K8S node name [GH-14] + * RBAC support for `connectInject`. This will create a `ClusterRole`, `ClusterRoleBinding`, + and `ServiceAccount` that is necessary for the connect injector to automatically generate + TLS certificates to interact with the Kubernetes API. BUG FIXES: From 00932578a5090c3d06b36f68ccec73f377c4e753 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 30 Oct 2018 14:22:09 -0700 Subject: [PATCH 092/739] Update to latest consul-k8s version Additional updates the Chart.yaml version to match the current 0.3.0 release. --- Chart.yaml | 2 +- values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Chart.yaml b/Chart.yaml index fd6761eeed..4894cc6aca 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.1.0 +version: 0.3.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index 6e81d70fbb..42fc985d03 100644 --- a/values.yaml +++ b/values.yaml @@ -21,7 +21,7 @@ global: # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.2.0" + imageK8S: "hashicorp/consul-k8s:0.2.1" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 6c29f297819486f92a68892fe15abd56c695d766 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 30 Oct 2018 15:08:49 -0700 Subject: [PATCH 093/739] Pipe through the default flag for catalog sync --- templates/sync-catalog-deployment.yaml | 1 + test/unit/sync-catalog-deployment.bats | 24 ++++++++++++++++++++++++ values.yaml | 1 + 3 files changed, 26 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 64ede66d0a..c876344425 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -49,6 +49,7 @@ spec: - | consul-k8s sync-catalog \ -http-addr=${HOST_IP}:8500 \ + -k8s-default-sync={{ .Values.syncCatalog.default }} \ {{- if (not .Values.syncCatalog.toConsul) }} -to-consul=false \ {{- end }} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index c7079e60c6..e020949254 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -68,6 +68,30 @@ load _helpers [ "${actual}" = "bar" ] } +#-------------------------------------------------------------------- +# default sync + +@test "syncCatalog/Deployment: default sync is true by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | any(contains("-k8s-default-sync=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: default sync can be turned off" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.default=false' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | any(contains("-k8s-default-sync=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # toConsul and toK8S diff --git a/values.yaml b/values.yaml index 42fc985d03..5160226668 100644 --- a/values.yaml +++ b/values.yaml @@ -146,6 +146,7 @@ syncCatalog: # True if you want to enable the catalog sync. "-" for default. enabled: false image: null + default: true # true will sync by default, otherwise requires annotation # Enabling rbac will create cluster roles and cluster role bindings to # allow the syncCatalog service to communicate with the kubernetes api From d549a97ab6fd0dc4323289aba4c8d2cecf053e2b Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 31 Oct 2018 15:54:51 -0700 Subject: [PATCH 094/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bc46579a2..d7d66e3247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ IMPROVEMENTS: BUG FIXES: + * Add catalog sync default behavior flag to the chart [GH-28] * Updated images to point to latest versions for 0.3.0. * Add missing continuation characters to long commands [GH-26]. * connectInject: set the correct namespace for the MutatingWebhookConfiguration From 3fa3e2d6334ba002edc5e6833b366a2da3dd9c01 Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Mon, 5 Nov 2018 21:02:54 +1000 Subject: [PATCH 095/739] Update formating of template Add test cases Improve variable commenting --- templates/server-statefulset.yaml | 4 ++-- test/unit/server-statefulset.bats | 21 +++++++++++++++++++++ values.yaml | 5 ++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 3e088c310d..90d3b20be2 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -39,8 +39,8 @@ spec: spec: {{- if .Values.server.affinity }} affinity: -{{ tpl .Values.server.affinity . | indent 8 }} -{{- end }} + {{ tpl .Values.server.affinity . | indent 8 }} + {{- end }} terminationGracePeriodSeconds: 10 securityContext: fsGroup: 1000 diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index edce61671d..2c25077edf 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -11,6 +11,27 @@ load _helpers [ "${actual}" = "true" ] } + +@test "server/StatefulSet: affinity not set with server.affinity" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.affinity=' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: affinity set with server.affinity as empty" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.affinity=""' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + @test "server/StatefulSet: enable with global.enabled false" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index 587c517331..47eccdee1f 100644 --- a/values.yaml +++ b/values.yaml @@ -80,8 +80,8 @@ server: # load: false # if true, will add to `-config-dir` to load by Consul # Affinity Settings - # Overriding this will allow deployment to single node services such as - # Minikube + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube affinity: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -92,7 +92,6 @@ server: component: server topologyKey: kubernetes.io/hostname - # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. From 40fa760b3cbb773feb3ae6f7e2ee0221cfbbce67 Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Mon, 5 Nov 2018 21:08:09 +1000 Subject: [PATCH 096/739] Fix to indent of variables --- templates/server-statefulset.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 90d3b20be2..a578114297 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -39,7 +39,7 @@ spec: spec: {{- if .Values.server.affinity }} affinity: - {{ tpl .Values.server.affinity . | indent 8 }} + {{ tpl .Values.server.affinity . }} {{- end }} terminationGracePeriodSeconds: 10 securityContext: From 8b6a862f5331669e977530d83427a980273b6e54 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 5 Nov 2018 16:27:06 -0800 Subject: [PATCH 097/739] Add information about writing bats unit tests This documentation gives a description of how the bats tests are structured, as well as giving several examples of common test patterns. --- README.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/README.md b/README.md index 0eb6ca0cf9..181a44a518 100644 --- a/README.md +++ b/README.md @@ -66,3 +66,111 @@ that can be used to quickly bring up a GKE cluster and configure `kubectl` and `helm` locally. This can be used to quickly spin up a test cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes cluster. + +### Writing Unit Tests + +Changes to the Helm chart should be accompanied by appropriate unit tests. + +#### Formatting + +- Put tests in the test file in the same order as the variables appear in the `values.yaml`. +- Start tests for a chart value with a header that says what is being tested, like this: + ``` + #-------------------------------------------------------------------- + # annotations + ``` + +- Name the test based on what it's testing in the following format: + ``` + { section being tested }: { short description of the test case } + ``` + + When adding tests to an existing file, the first section will be the same as the other tests in the file. + +#### Test Details + +[Bats](https://github.com/bats-core/bats-core) provides a way to run commands in a shell and inspect the output in an automated way. +In all of the tests in this repo, the base command being run is [helm template](https://docs.helm.sh/helm/#helm-template) which turns the templated files into straight yaml output. +In this way, we're able to test that the various conditionals in the templates render as we would expect. + +Each test defines the files that should be rendered using the `-x` flag, then it might adjust chart values by adding `--set` flags as well. +The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). +`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). + +The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. + +The `| tee /dev/stderr ` pieces direct any terminal output of the `helm template` and `yq` commands to stderr so that it doesn't interfere with `bats`. + +#### Test Examples + +Here are some examples of common test patterns: + +- Check that a value is disabled by default + + ``` + @test "ui/Service: no type by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "null" ] + } + ``` + + In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. + This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]` + + +- Check that a template value is rendered to a specific value + ``` + @test "ui/Service: specified type" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] + } + ``` + + This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. + + - Check that a template value contains several values + ``` + @test "syncCatalog/Deployment: to-k8s only" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-consul=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + In this case, the same command is run twice in the same test. + This can be used to look for several things in the same field, or to check that something is not present that shouldn't be. + +- Check that an entire template file is not rendered + ``` + @test "syncCatalog/Deployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + Here we are check the length of the command output to see if the anything is rendered. + This style can easily be switched to check that a file is rendered instead. From e8d041284eba585671b4c583277d1bf797c1b0b5 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 7 Nov 2018 11:58:07 -0800 Subject: [PATCH 098/739] Clarify the test naming guidelines Clarified the test naming by including the full first line pattern that includes the name. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 181a44a518..4f87fd32b2 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,9 @@ Changes to the Helm chart should be accompanied by appropriate unit tests. # annotations ``` -- Name the test based on what it's testing in the following format: +- Name the test based on what it's testing in the following format (this will be its first line): ``` - { section being tested }: { short description of the test case } + @test "
: " { ``` When adding tests to an existing file, the first section will be the same as the other tests in the file. @@ -95,7 +95,8 @@ In this way, we're able to test that the various conditionals in the templates r Each test defines the files that should be rendered using the `-x` flag, then it might adjust chart values by adding `--set` flags as well. The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). -`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). +`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). +The `-r` flag can be used with `yq` to return a raw string instead of a quoted one which is especially useful when looking for an exact match. The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. @@ -119,7 +120,7 @@ Here are some examples of common test patterns: ``` In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. - This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]` + This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]`. - Check that a template value is rendered to a specific value @@ -137,7 +138,7 @@ Here are some examples of common test patterns: This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. - - Check that a template value contains several values +- Check that a template value contains several values ``` @test "syncCatalog/Deployment: to-k8s only" { cd `chart_dir` From 8c4cff9401322c2f17c63ca7ce276177ca8aa577 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 7 Nov 2018 12:16:24 -0800 Subject: [PATCH 099/739] Add note about testing more than two conditions in one test For testing two conditions in the same test, it is reasonable to follow the existing test patterns and run `helm template` each time. When testing more conditions, it starts to make sense to separate the rendering of the yaml from the condition finding and testing. This commit adds a note to that effect. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4f87fd32b2..80686d025d 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,8 @@ Here are some examples of common test patterns: In this case, the same command is run twice in the same test. This can be used to look for several things in the same field, or to check that something is not present that shouldn't be. + *Note:* If testing more than two conditions, it would be good to separate the `helm template` part of the command from the `yq` sections to reduce redundant work. + - Check that an entire template file is not rendered ``` @test "syncCatalog/Deployment: disabled by default" { From 4124373fb785291030790c2b32857defad3f680d Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Thu, 8 Nov 2018 11:21:19 +1000 Subject: [PATCH 100/739] Fix tests to check for null and default, resolve indent of template --- templates/server-statefulset.yaml | 2 +- test/unit/server-statefulset.bats | 43 ++++++++++++++++--------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 9384617f0b..fd02202440 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -39,7 +39,7 @@ spec: spec: {{- if .Values.server.affinity }} affinity: - {{ tpl .Values.server.affinity . }} + {{ tpl .Values.server.affinity . | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: 10 securityContext: diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 2c25077edf..f1bc2c9d1d 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -11,27 +11,6 @@ load _helpers [ "${actual}" = "true" ] } - -@test "server/StatefulSet: affinity not set with server.affinity" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'server.affinity=' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "server/StatefulSet: affinity set with server.affinity as empty" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'server.affinity=""' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - @test "server/StatefulSet: enable with global.enabled false" { cd `chart_dir` local actual=$(helm template \ @@ -113,6 +92,28 @@ load _helpers [ "${actual}" = "2" ] } +#-------------------------------------------------------------------- +# affinity + +@test "server/StatefulSet: affinity not set with server.affinity" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.affinity=null' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .affinity? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: affinity set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.affinity | .podAntiAffinity? != null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # extraVolumes From 57b479e4ba29ccc5bf7b43373f6da144a3ea1168 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 8 Nov 2018 11:43:12 -0800 Subject: [PATCH 101/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d66e3247..087c8c9565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ IMPROVEMENTS: * RBAC support for `connectInject`. This will create a `ClusterRole`, `ClusterRoleBinding`, and `ServiceAccount` that is necessary for the connect injector to automatically generate TLS certificates to interact with the Kubernetes API. + * Server affinity is now configurable. This makes it easier to run an entire + Consul cluster on Minikube. [GH-13] BUG FIXES: From e29b54842b9df4675e78c37cebda90a4c9cce6e5 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 8 Nov 2018 17:28:56 -0800 Subject: [PATCH 102/739] Remove rbac option for sync catalog This removes the option to disable the RBAC setup for sync-catalog. In most cases, this is necessary for the functionality to work correctly and there isn't a good use case for disabling it. Additionally, this now mirrors the connect-inject implementation and simplifies the logic for things that augment RBAC, like pod security policies. --- .../sync-catalog-cluster-role-binding.yaml | 3 +-- templates/sync-catalog-cluster-role.yaml | 3 +-- templates/sync-catalog-deployment.yaml | 5 +--- templates/sync-catalog-service-account.yaml | 3 +-- .../sync-catalog-cluster-role-binding.bats | 26 ++++++++----------- test/unit/sync-catalog-cluster-role.bats | 24 +++++++---------- test/unit/sync-catalog-deployment.bats | 3 +-- test/unit/sync-service-account.bats | 24 +++++++---------- values.yaml | 6 ----- 9 files changed, 36 insertions(+), 61 deletions(-) diff --git a/templates/sync-catalog-cluster-role-binding.yaml b/templates/sync-catalog-cluster-role-binding.yaml index 431ef05e7a..648bd30727 100644 --- a/templates/sync-catalog-cluster-role-binding.yaml +++ b/templates/sync-catalog-cluster-role-binding.yaml @@ -1,6 +1,5 @@ -{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (and $rbacEnabled $syncEnabled) }} +{{- if $syncEnabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml index 4dc398f0ab..9c88fa1a09 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -1,6 +1,5 @@ -{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (and $rbacEnabled $syncEnabled) }} +{{- if $syncEnabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index c876344425..df833709d8 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -1,5 +1,4 @@ -# The deployment for running the Connect sidecar injector -{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} +# The deployment for running the sync-catalog pod {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: apps/v1 kind: Deployment @@ -28,9 +27,7 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" spec: - {{- if $rbacEnabled }} serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog - {{- end }} containers: - name: consul-sync-catalog image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" diff --git a/templates/sync-catalog-service-account.yaml b/templates/sync-catalog-service-account.yaml index b8d997172f..0c4291e5ca 100644 --- a/templates/sync-catalog-service-account.yaml +++ b/templates/sync-catalog-service-account.yaml @@ -1,6 +1,5 @@ -{{- $rbacEnabled := (or (and (ne (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.syncCatalog.rbac.enabled) (and (eq (.Values.syncCatalog.rbac.enabled | toString) "-") .Values.global.enabled)) }} {{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (and $rbacEnabled $syncEnabled) }} +{{- if $syncEnabled }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/test/unit/sync-catalog-cluster-role-binding.bats b/test/unit/sync-catalog-cluster-role-binding.bats index 21e80e4973..3b0434f146 100755 --- a/test/unit/sync-catalog-cluster-role-binding.bats +++ b/test/unit/sync-catalog-cluster-role-binding.bats @@ -11,47 +11,43 @@ load _helpers [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: enable with global.enabled false" { +@test "sync/ClusterRoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'global.enabled=false' \ - --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | - yq -s 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: disable with syncCatalog.enabled" { +@test "sync/ClusterRoleBinding: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=false' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: disable with syncCatalog.rbac.enabled" { +@test "sync/ClusterRoleBinding: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role-binding.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "sync/ClusterRoleBinding: disable with global.enabled" { +@test "sync/ClusterRoleBinding: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role-binding.yaml \ - --set 'syncCatalog.rbac.enabled="-"' \ --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } diff --git a/test/unit/sync-catalog-cluster-role.bats b/test/unit/sync-catalog-cluster-role.bats index 3e08bad568..557c9e50a5 100755 --- a/test/unit/sync-catalog-cluster-role.bats +++ b/test/unit/sync-catalog-cluster-role.bats @@ -11,47 +11,43 @@ load _helpers [ "${actual}" = "false" ] } -@test "sync/ClusterRole: enable with global.enabled false" { +@test "sync/ClusterRole: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role.yaml \ --set 'global.enabled=false' \ - --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | - yq -s 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } -@test "sync/ClusterRole: disable with syncCatalog.enabled" { +@test "sync/ClusterRole: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role.yaml \ --set 'syncCatalog.enabled=false' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRole: disable with rbac.enabled" { +@test "sync/ClusterRole: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } -@test "sync/ClusterRole: disable with global.enabled" { +@test "sync/ClusterRole: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-cluster-role.yaml \ --set 'global.enabled=false' \ - --set 'syncCatalog.rbac.enabled="-"' \ + --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index e020949254..f2e40e90c4 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -177,12 +177,11 @@ load _helpers #-------------------------------------------------------------------- # serviceAccount -@test "syncCatalog/Deployment: serviceAccount set with rbac.enabled" { +@test "syncCatalog/Deployment: serviceAccount set when sync enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.serviceAccountName | contains("sync-catalog")' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/sync-service-account.bats b/test/unit/sync-service-account.bats index 5a49d5cc8e..27238e2840 100755 --- a/test/unit/sync-service-account.bats +++ b/test/unit/sync-service-account.bats @@ -11,47 +11,43 @@ load _helpers [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: enable with global.enabled false" { +@test "sync/ServiceAccount: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-service-account.yaml \ --set 'global.enabled=false' \ - --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | - yq -s 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: disable with syncCatalog.enabled" { +@test "sync/ServiceAccount: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-service-account.yaml \ --set 'syncCatalog.enabled=false' \ - --set 'syncCatalog.rbac.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: disable with syncCatalog.rbac.enabled" { +@test "sync/ServiceAccount: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-service-account.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.rbac.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } -@test "sync/ServiceAccount: disable with global.enabled" { +@test "sync/ServiceAccount: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-service-account.yaml \ - --set 'syncCatalog.rbac.enabled="-"' \ --set 'global.enabled=false' \ + --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } diff --git a/values.yaml b/values.yaml index 827fb8f41d..f18f4d1640 100644 --- a/values.yaml +++ b/values.yaml @@ -161,12 +161,6 @@ syncCatalog: image: null default: true # true will sync by default, otherwise requires annotation - # Enabling rbac will create cluster roles and cluster role bindings to - # allow the syncCatalog service to communicate with the kubernetes api - # to get/create services. - rbac: - enabled: true - # toConsul and toK8S control whether syncing is enabled to Consul or K8S # as a destination. If both of these are disabled, the sync will do nothing. toConsul: true From cf76a2d2d5761015156a735c9432cc24bfb0fa3d Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 9 Nov 2018 16:19:50 -0800 Subject: [PATCH 103/739] Provide a valid maxUnavailable value when using a single replica This adds a condition to set `maxUnavailable` to 0 when replicas=1. Previously, the logic returned an invalid value of `-1`. The larger issue of not being able to set something explicitly to 0 remains, as this is a limitation of the way helm templating works. For more information, see: Helm documentation that a numerical 0 is treated identically to null: https://docs.helm.sh/chart_template_guide/#if-else Github issue for this: https://github.com/helm/helm/issues/3164 --- templates/_helpers.tpl | 5 ++++- test/unit/server-disruptionbudget.bats | 28 +++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index ec9e77359b..6ba475d31d 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -34,9 +34,12 @@ Expand the name of the chart. {{/* Compute the maximum number of unavailable replicas for the PodDisruptionBudget. This defaults to (n/2)-1 where n is the number of members of the server cluster. +Add a special case for replicas=1, where it should default to 0 as well. */}} {{- define "consul.pdb.maxUnavailable" -}} -{{- if .Values.server.disruptionBudget.maxUnavailable -}} +{{- if eq (int .Values.server.replicas) 1 -}} +{{ 0 }} +{{- else if .Values.server.disruptionBudget.maxUnavailable -}} {{ .Values.server.disruptionBudget.maxUnavailable -}} {{- else -}} {{- ceil (sub (div (int .Values.server.replicas) 2) 1) -}} diff --git a/test/unit/server-disruptionbudget.bats b/test/unit/server-disruptionbudget.bats index c2f2e988f0..28e8d0d518 100755 --- a/test/unit/server-disruptionbudget.bats +++ b/test/unit/server-disruptionbudget.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "server/DisruptionBudget: enable with global.enabled false" { +@test "server/DisruptionBudget: enabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -22,7 +22,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "server/DisruptionBudget: disable with server.enabled" { +@test "server/DisruptionBudget: disabled with server.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -32,7 +32,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "server/DisruptionBudget: disable with server.disruptionBudget.enabled" { +@test "server/DisruptionBudget: disabled with server.disruptionBudget.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -42,7 +42,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "server/DisruptionBudget: disable with global.enabled" { +@test "server/DisruptionBudget: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -52,7 +52,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "server/DisruptionBudget: correct maxUnavailable with n=3" { +#-------------------------------------------------------------------- +# maxUnavailable + +@test "server/DisruptionBudget: correct maxUnavailable with replicas=3" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -61,3 +64,18 @@ load _helpers yq '.spec.maxUnavailable' | tee /dev/stderr) [ "${actual}" = "0" ] } + +@test "server/DisruptionBudget: correct maxUnavailable with replicas=1" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=1' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +# Note: It is not possible to test anything but the default behavior of the +# maxUnavailable definition in the _helpers.tpl with the current test setup +# because the `--set` flag overrides values AFTER they're been run through +# the helper functions. From 0757d9ddef78c0eb5043495db8a2de20b68cc39f Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 12 Nov 2018 10:54:37 -0800 Subject: [PATCH 104/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 087c8c9565..b0b6a25752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ BUG FIXES: * Add missing continuation characters to long commands [GH-26]. * connectInject: set the correct namespace for the MutatingWebhookConfiguration so that deployments work in non-default namespaces. [GH-41] + * Provide a valid `maxUnavailable` value when replicas=1. [GH-58] ## 0.3.0 (October 11, 2018) From 48cdf853dbca1f81ecd85e76804d33dffcf48f5a Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 12 Nov 2018 11:14:41 -0800 Subject: [PATCH 105/739] Update CHANGELOG.md --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b6a25752..9e9e10041b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,8 @@ IMPROVEMENTS: - * RBAC support for `syncCatalog`. This is enabled by default if the catalog - sync is enabled but can be controlled with `syncCatalog.rbac.enabled`. - This will create the `ClusterRole` and `ClusterRoleBinding` necessary - for the catalog sync. [GH-29] + * RBAC support for `syncCatalog`. This will create the `ClusterRole`, `ClusterRoleBinding` + and `ServiceAccount` that is necessary for the catalog sync. [GH-29] * client: agents now have the node name set to the actual K8S node name [GH-14] * RBAC support for `connectInject`. This will create a `ClusterRole`, `ClusterRoleBinding`, and `ServiceAccount` that is necessary for the connect injector to automatically generate From 50e9f3446af1987b0ffaa9d8ebbc6d07504a34c3 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 12 Nov 2018 12:11:33 -0800 Subject: [PATCH 106/739] Make sure that provided join information is properly quoted Especially for auto-join using go-discover, the resultant string needs to have quotes to be passed correctly. --- templates/client-daemonset.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 56edd6b2a9..754183278d 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -89,7 +89,7 @@ spec: -data-dir=/consul/data \ {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} {{- range $value := .Values.client.join }} - -retry-join={{ $value }} \ + -retry-join="{{ $value }}" \ {{- end }} {{- else }} {{- if .Values.server.enabled }} From ad36ca047d31a29a482b840ba1bb7e091947242a Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 12 Nov 2018 14:16:24 -0800 Subject: [PATCH 107/739] Pass server resource limits on to the pods in the stateful set The values.yaml allowed users to define resource limitations for the server pods, but was not applying these to the pods in the server-statefulset.yaml. This fixes that oversight. --- templates/server-statefulset.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index fd02202440..6e6aea8a83 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -146,6 +146,8 @@ spec: periodSeconds: 3 successThreshold: 1 timeoutSeconds: 5 + resources: +{{ toYaml .Values.server.resources | indent 12 }} volumeClaimTemplates: - metadata: name: data From aab7a813a4ded3f6649adbb4fddc38ccb8770a32 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 19 Nov 2018 14:12:07 -0800 Subject: [PATCH 108/739] Switch liveness probe to an http call The TCP check against the port was passing in Kubernetes view because something responded, even though it couldn't connect because it didn't have the correct credentials. This left lots of unnecessary error messages in the logs. --- templates/connect-inject-deployment.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index cfab92b304..0589c6cf06 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -57,8 +57,10 @@ spec: -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc {{- end }} livenessProbe: - tcpSocket: + httpGet: + path: /health/ready port: 8080 + scheme: HTTPS failureThreshold: 2 initialDelaySeconds: 1 periodSeconds: 2 From 2bfcb1c1bf135699e6b880f7512c7c5b029be997 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 20 Nov 2018 09:39:25 -0800 Subject: [PATCH 109/739] Switch resource definitions to multi-line strings These values now default to null and are optional in the template files. Adds tests for the new values. Also changes the file extension on several of the test files from .yaml to .bats. --- templates/client-daemonset.yaml | 4 +- templates/server-statefulset.yaml | 4 +- ...t-daemonset.yaml => client-daemonset.bats} | 22 +++++++ ...ml => connect-inject-mutatingwebhook.bats} | 0 ...rvice.yaml => connect-inject-service.bats} | 0 test/unit/server-statefulset.bats | 61 +++++++++++++------ values.yaml | 14 +++-- 7 files changed, 78 insertions(+), 27 deletions(-) rename test/unit/{client-daemonset.yaml => client-daemonset.bats} (90%) rename test/unit/{connect-inject-mutatingwebhook.yaml => connect-inject-mutatingwebhook.bats} (100%) rename test/unit/{connect-inject-service.yaml => connect-inject-service.bats} (100%) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 754183278d..9d0dddb1bd 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -145,6 +145,8 @@ spec: - | curl http://127.0.0.1:8500/v1/status/leader 2>/dev/null | \ grep -E '".+"' + {{- if .Values.client.resources }} resources: -{{ toYaml .Values.client.resources | indent 12 }} + {{ tpl .Values.client.resources . | nindent 12 | trim }} + {{- end }} {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 6e6aea8a83..5427cbd524 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -146,8 +146,10 @@ spec: periodSeconds: 3 successThreshold: 1 timeoutSeconds: 5 + {{- if .Values.server.resources }} resources: -{{ toYaml .Values.server.resources | indent 12 }} + {{ tpl .Values.server.resources . | nindent 12 | trim }} + {{- end }} volumeClaimTemplates: - metadata: name: data diff --git a/test/unit/client-daemonset.yaml b/test/unit/client-daemonset.bats similarity index 90% rename from test/unit/client-daemonset.yaml rename to test/unit/client-daemonset.bats index 2b9dbdc53e..9544d55ff3 100755 --- a/test/unit/client-daemonset.yaml +++ b/test/unit/client-daemonset.bats @@ -94,6 +94,28 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# resources + +@test "client/DaemonSet: no resources defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/DaemonSet: resources can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.resources=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + #-------------------------------------------------------------------- # extraVolumes diff --git a/test/unit/connect-inject-mutatingwebhook.yaml b/test/unit/connect-inject-mutatingwebhook.bats similarity index 100% rename from test/unit/connect-inject-mutatingwebhook.yaml rename to test/unit/connect-inject-mutatingwebhook.bats diff --git a/test/unit/connect-inject-service.yaml b/test/unit/connect-inject-service.bats similarity index 100% rename from test/unit/connect-inject-service.yaml rename to test/unit/connect-inject-service.bats diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index f1bc2c9d1d..db1a31cbcd 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -42,6 +42,9 @@ load _helpers [ "${actual}" = "false" ] } +#-------------------------------------------------------------------- +# image + @test "server/StatefulSet: image defaults to global.image" { cd `chart_dir` local actual=$(helm template \ @@ -64,7 +67,29 @@ load _helpers } #-------------------------------------------------------------------- -# updateStrategy +# resources + +@test "server/StatefulSet: no resources defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/StatefulSet: resources can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.resources=foo' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = "foo" ] +} + +#-------------------------------------------------------------------- +# updateStrategy (derived from updatePartition) @test "server/StatefulSet: no updateStrategy when not updating" { cd `chart_dir` @@ -93,25 +118,25 @@ load _helpers } #-------------------------------------------------------------------- -# affinity +# storageClass -@test "server/StatefulSet: affinity not set with server.affinity" { +@test "server/StatefulSet: no storageClass on claim by default" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'server.affinity=null' \ . | tee /dev/stderr | - yq '.spec.template.spec | .affinity? == null' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] } -@test "server/StatefulSet: affinity set by default" { +@test "server/StatefulSet: can set storageClass" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ + --set 'server.storageClass=foo' \ . | tee /dev/stderr | - yq '.spec.template.spec.affinity | .podAntiAffinity? != null' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) + [ "${actual}" = "foo" ] } #-------------------------------------------------------------------- @@ -220,25 +245,23 @@ load _helpers } #-------------------------------------------------------------------- -# updateStrategy +# affinity -@test "server/StatefulSet: no storageClass on claim by default" { +@test "server/StatefulSet: affinity not set with server.affinity=null" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ + --set 'server.affinity=null' \ . | tee /dev/stderr | - yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq '.spec.template.spec | .affinity? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] } - -@test "server/StatefulSet: can set storageClass" { +@test "server/StatefulSet: affinity set by default" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'server.storageClass=foo' \ . | tee /dev/stderr | - yq -r '.spec.volumeClaimTemplates[0].spec.storageClassName' | tee /dev/stderr) - [ "${actual}" = "foo" ] + yq '.spec.template.spec.affinity | .podAntiAffinity? != null' | tee /dev/stderr) + [ "${actual}" = "true" ] } - diff --git a/values.yaml b/values.yaml index f18f4d1640..29cb44fe8f 100644 --- a/values.yaml +++ b/values.yaml @@ -48,9 +48,10 @@ server: connect: true # Resource requests, limits, etc. for the server cluster placement. This - # should map directly to the value of the resources field for a PodSpec. - # By default no direct resource request is made. - resources: {} + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: null # updatePartition is used to control a careful rolling update of Consul # servers. This should be done particularly when changing the version @@ -105,9 +106,10 @@ client: grpc: false # Resource requests, limits, etc. for the client cluster placement. This - # should map directly to the value of the resources field for a PodSpec. - # By default no direct resource request is made. - resources: {} + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: null # extraConfig is a raw string of extra configuration to set with the # server. This should be JSON. From 64b221a46c1157628b40abbf3400cc489e73ca9b Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 20 Nov 2018 10:46:42 -0800 Subject: [PATCH 110/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e9e10041b..06a341ea71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ IMPROVEMENTS: TLS certificates to interact with the Kubernetes API. * Server affinity is now configurable. This makes it easier to run an entire Consul cluster on Minikube. [GH-13] + * Liveness probes are now http calls, reducing errors in the logs. BUG FIXES: From ec0de4185681d352f3f7814407002819b2642f34 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 20 Nov 2018 10:48:11 -0800 Subject: [PATCH 111/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06a341ea71..f9539bdbef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ BUG FIXES: * connectInject: set the correct namespace for the MutatingWebhookConfiguration so that deployments work in non-default namespaces. [GH-41] * Provide a valid `maxUnavailable` value when replicas=1. [GH-58] + * Correctly sets server resource requirements. ## 0.3.0 (October 11, 2018) From 83fb1a292fc95237145a492d33f1647c9e45cfe7 Mon Sep 17 00:00:00 2001 From: Ethan Goldblum Date: Thu, 29 Nov 2018 12:26:10 -0800 Subject: [PATCH 112/739] Add namespace to all namespaced resources --- templates/client-config-configmap.yaml | 1 + templates/client-daemonset.yaml | 1 + templates/connect-inject-deployment.yaml | 1 + templates/connect-inject-mutatingwebhook.yaml | 1 + templates/connect-inject-service.yaml | 1 + templates/dns-service.yaml | 1 + templates/server-config-configmap.yaml | 1 + templates/server-disruptionbudget.yaml | 1 + templates/server-service.yaml | 1 + templates/server-statefulset.yaml | 1 + templates/sync-catalog-deployment.yaml | 1 + templates/ui-service.yaml | 1 + 12 files changed, 12 insertions(+) diff --git a/templates/client-config-configmap.yaml b/templates/client-config-configmap.yaml index 1bf88baf27..9d2ddc57d2 100644 --- a/templates/client-config-configmap.yaml +++ b/templates/client-config-configmap.yaml @@ -5,6 +5,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ template "consul.fullname" . }}-client-config + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 9d0dddb1bd..4cfd123b2b 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -4,6 +4,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: name: {{ template "consul.fullname" . }} + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 0589c6cf06..3564e128a9 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -4,6 +4,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ template "consul.fullname" . }}-connect-injector-webhook-deployment + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 47e6b80023..4138895c51 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -4,6 +4,7 @@ apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: {{ template "consul.fullname" . }}-connect-injector-cfg + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml index 86a13ca2be..45dc2b32db 100644 --- a/templates/connect-inject-service.yaml +++ b/templates/connect-inject-service.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: Service metadata: name: {{ template "consul.fullname" . }}-connect-injector-svc + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index 40846fba31..cdedaf2a96 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: Service metadata: name: {{ template "consul.fullname" . }}-dns + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 41b1f2f1c4..79171c1e7a 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ template "consul.fullname" . }}-server-config + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index 0470de73bd..01bef39964 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -5,6 +5,7 @@ apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 902abe0a24..9a208699f5 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -8,6 +8,7 @@ apiVersion: v1 kind: Service metadata: name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 5427cbd524..5eccdacb57 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -4,6 +4,7 @@ apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index df833709d8..9877e3f79b 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -4,6 +4,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ template "consul.fullname" . }}-sync-catalog + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index f0c9784d83..55fb4abd5e 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -8,6 +8,7 @@ apiVersion: v1 kind: Service metadata: name: {{ template "consul.fullname" . }}-ui + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} From 9c07a1a1bc852e6af0092cd8052798ed58b6163c Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Wed, 5 Dec 2018 16:34:30 +1000 Subject: [PATCH 113/739] Deal with the sprig library using int for sub and div values --- templates/_helpers.tpl | 8 +++- test/unit/server-disruptionbudget.bats | 53 +++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index ec9e77359b..9f59611745 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -34,11 +34,17 @@ Expand the name of the chart. {{/* Compute the maximum number of unavailable replicas for the PodDisruptionBudget. This defaults to (n/2)-1 where n is the number of members of the server cluster. +Special case of replica equaling 3 and allowing a minor disruption of 1 otherwise +use the integer value */}} {{- define "consul.pdb.maxUnavailable" -}} {{- if .Values.server.disruptionBudget.maxUnavailable -}} {{ .Values.server.disruptionBudget.maxUnavailable -}} {{- else -}} -{{- ceil (sub (div (int .Values.server.replicas) 2) 1) -}} +{{- if eq (int .Values.server.replicas) 3 -}} +{{- 1 -}} +{{- else -}} +{{- sub (div (int .Values.server.replicas) 2) 1 -}} +{{- end -}} {{- end -}} {{- end -}} diff --git a/test/unit/server-disruptionbudget.bats b/test/unit/server-disruptionbudget.bats index c2f2e988f0..2141ad32fe 100755 --- a/test/unit/server-disruptionbudget.bats +++ b/test/unit/server-disruptionbudget.bats @@ -59,5 +59,56 @@ load _helpers --set 'server.replicas=3' \ . | tee /dev/stderr | yq '.spec.maxUnavailable' | tee /dev/stderr) - [ "${actual}" = "0" ] + [ "${actual}" = "1" ] } + +@test "server/DisruptionBudget: correct maxUnavailable with n=4" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=4' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + + +@test "server/DisruptionBudget: correct maxUnavailable with n=5" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=5' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "server/DisruptionBudget: correct maxUnavailable with n=6" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=6' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "server/DisruptionBudget: correct maxUnavailable with n=7" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=7' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "server/DisruptionBudget: correct maxUnavailable with n=8" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-disruptionbudget.yaml \ + --set 'server.replicas=8' \ + . | tee /dev/stderr | + yq '.spec.maxUnavailable' | tee /dev/stderr) + [ "${actual}" = "3" ] +} \ No newline at end of file From 8737581651df055a5709d43f013a1baeed8e3a3c Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Thu, 6 Dec 2018 09:35:08 +1000 Subject: [PATCH 114/739] Fix test naming for consistancy --- test/unit/server-disruptionbudget.bats | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit/server-disruptionbudget.bats b/test/unit/server-disruptionbudget.bats index 03238c372e..b9b543b7b8 100755 --- a/test/unit/server-disruptionbudget.bats +++ b/test/unit/server-disruptionbudget.bats @@ -75,7 +75,7 @@ load _helpers [ "${actual}" = "1" ] } -@test "server/DisruptionBudget: correct maxUnavailable with n=4" { +@test "server/DisruptionBudget: correct maxUnavailable with replicas=4" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -86,7 +86,7 @@ load _helpers } -@test "server/DisruptionBudget: correct maxUnavailable with n=5" { +@test "server/DisruptionBudget: correct maxUnavailable with replicas=5" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -96,7 +96,7 @@ load _helpers [ "${actual}" = "1" ] } -@test "server/DisruptionBudget: correct maxUnavailable with n=6" { +@test "server/DisruptionBudget: correct maxUnavailable with replicas=6" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -106,7 +106,7 @@ load _helpers [ "${actual}" = "2" ] } -@test "server/DisruptionBudget: correct maxUnavailable with n=7" { +@test "server/DisruptionBudget: correct maxUnavailable with replicas=7" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ @@ -116,7 +116,7 @@ load _helpers [ "${actual}" = "2" ] } -@test "server/DisruptionBudget: correct maxUnavailable with n=8" { +@test "server/DisruptionBudget: correct maxUnavailable with replicas=8" { cd `chart_dir` local actual=$(helm template \ -x templates/server-disruptionbudget.yaml \ From 28b79488e4da0ce7b39150e65dc2db4e7fb04d2c Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 5 Dec 2018 15:53:49 -0800 Subject: [PATCH 115/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9539bdbef..cac64722ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ BUG FIXES: so that deployments work in non-default namespaces. [GH-41] * Provide a valid `maxUnavailable` value when replicas=1. [GH-58] * Correctly sets server resource requirements. + * Update the `maxUnavailable` default calculation to allow rolling updates on 3 server clusters. [GH-71] ## 0.3.0 (October 11, 2018) From 9149ca08d10efec61c3915157083979f72e0c584 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 5 Dec 2018 18:20:41 -0800 Subject: [PATCH 116/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cac64722ff..6ee67b1317 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ IMPROVEMENTS: * Server affinity is now configurable. This makes it easier to run an entire Consul cluster on Minikube. [GH-13] * Liveness probes are now http calls, reducing errors in the logs. + * All namespaced resources now specify the namespace metadata, making `helm template` usage in + a non-default namespace easier. [GH-66] BUG FIXES: From 76620db0a905d5f36c035bd8d28ae2f03cf66c38 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 6 Dec 2018 18:55:04 -0800 Subject: [PATCH 117/739] Add `syncClusterIPServices` to the values file This supports the new optional functionality in `consul-k8s` to sync ClusterIP-type services. --- templates/sync-catalog-deployment.yaml | 5 ++++- values.yaml | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 9877e3f79b..204dca1d36 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -58,5 +58,8 @@ spec: {{- if .Values.syncCatalog.k8sPrefix }} -k8s-service-prefix="{{ .Values.syncCatalog.k8sPrefix}}" \ {{- end }} - -k8s-write-namespace=${NAMESPACE} + -k8s-write-namespace=${NAMESPACE} \ + {{- if (not .Values.syncCatalog.syncClusterIPServices) }} + -sync-clusterip-services=false + {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index 29cb44fe8f..9f698617fd 100644 --- a/values.yaml +++ b/values.yaml @@ -173,6 +173,11 @@ syncCatalog: # prepended with "consul-". k8sPrefix: null + # syncClusterIPServices syncs services of the ClusterIP type, which may + # or may not be broadly accessible depending on your Kubernetes cluster. + # Set this to false to skip syncing ClusterIP services. + syncClusterIPServices: true + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false From e4248c7c4750344925deff47ea39ccb883931100 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 7 Dec 2018 15:46:34 -0800 Subject: [PATCH 118/739] Update default images to later versions --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 9f698617fd..4cb65bc434 100644 --- a/values.yaml +++ b/values.yaml @@ -16,12 +16,12 @@ global: # Image is the name (and tag) of the Consul Docker image for clients and # servers below. This can be overridden per component. - image: "consul:1.3.0" + image: "consul:1.3.1" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.2.1" + imageK8S: "hashicorp/consul-k8s:0.3.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From b03e92c2d0efb3906c9fc85347aa97afeeaba4c2 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 7 Dec 2018 16:38:57 -0800 Subject: [PATCH 119/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ee67b1317..da0ac72134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ IMPROVEMENTS: * Liveness probes are now http calls, reducing errors in the logs. * All namespaced resources now specify the namespace metadata, making `helm template` usage in a non-default namespace easier. [GH-66] + * Add support for ClusterIP service syncing. BUG FIXES: From 60c9cac7ceab85b13fdea019faefd83b7851238e Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 7 Dec 2018 16:41:41 -0800 Subject: [PATCH 120/739] Update chart version and changelog to 0.4.0 for release --- CHANGELOG.md | 2 ++ Chart.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da0ac72134..f028a76212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## UNRELEASED +## 0.4.0 (December 7, 2018) + IMPROVEMENTS: * RBAC support for `syncCatalog`. This will create the `ClusterRole`, `ClusterRoleBinding` diff --git a/Chart.yaml b/Chart.yaml index 4894cc6aca..ce093daacf 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.3.0 +version: 0.4.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 32e0d4c0355541fe44e9b08eac082610e89dc6ab Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 7 Jan 2019 17:15:27 -0800 Subject: [PATCH 121/739] Add support for NodePort syncing with node ip addresses Updates the service account permissions as well as adding an option for choosing which type of NodePort syncing is preferred. --- templates/sync-catalog-cluster-role.yaml | 1 + templates/sync-catalog-deployment.yaml | 3 +++ values.yaml | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml index 9c88fa1a09..101dcd77d7 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -14,6 +14,7 @@ rules: resources: - services - endpoints + - nodes verbs: - get - list diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 204dca1d36..ab8309a0ac 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -62,4 +62,7 @@ spec: {{- if (not .Values.syncCatalog.syncClusterIPServices) }} -sync-clusterip-services=false {{- end }} + {{- if .Values.syncCatalog.nodePortSyncType }} + -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} + {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index 4cb65bc434..e1c97b9e30 100644 --- a/values.yaml +++ b/values.yaml @@ -178,6 +178,14 @@ syncCatalog: # Set this to false to skip syncing ClusterIP services. syncClusterIPServices: true + # nodePortSyncType configures the type of syncing that happens for NodePort + # services. The valid options are: ExternalOnly, InternalOnly, ExternalFirst. + # - ExternalOnly will only use a node's ExternalIP address for the sync + # - InternalOnly use's the node's InternalIP address + # - ExternalFirst will preferentially use the node's ExternalIP address, but + # if it doesn't exist, it will use the node's InternalIP address instead. + nodePortSyncType: ExternalOnly + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false From 980f5b6eca02398e1eac1d5bf8316b4d906880b1 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 11 Jan 2019 10:28:53 -0800 Subject: [PATCH 122/739] Support consul-k8s-tag in the Helm chart Additionally adds a missing continuation flag for the catalog sync command. --- templates/sync-catalog-deployment.yaml | 7 +++++-- values.yaml | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index ab8309a0ac..bd430c18c3 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -60,9 +60,12 @@ spec: {{- end }} -k8s-write-namespace=${NAMESPACE} \ {{- if (not .Values.syncCatalog.syncClusterIPServices) }} - -sync-clusterip-services=false + -sync-clusterip-services=false \ {{- end }} {{- if .Values.syncCatalog.nodePortSyncType }} - -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} + -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} \ + {{- end }} + {{- if .Values.syncCatalog.k8sTag }} + -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index e1c97b9e30..7e6f5ed9a0 100644 --- a/values.yaml +++ b/values.yaml @@ -170,9 +170,14 @@ syncCatalog: # k8sPrefix is the service prefix to prepend to services before registering # with Kubernetes. For example "consul-" will register all services - # prepended with "consul-". + # prepended with "consul-". (Consul -> Kubernetes sync) k8sPrefix: null + # k8sTag is an optional tag that is applied to all of the Kubernetes services + # that are synced into Consul. If nothing is set, defaults to "k8s". + # (Kubernetes -> Consul sync) + k8sTag: null + # syncClusterIPServices syncs services of the ClusterIP type, which may # or may not be broadly accessible depending on your Kubernetes cluster. # Set this to false to skip syncing ClusterIP services. From e09d6ab8061d73cbf60822a5db3f035cdd247e91 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 11 Jan 2019 11:20:41 -0800 Subject: [PATCH 123/739] Restrict node permissions to only the necessary `get` --- templates/sync-catalog-cluster-role.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml index 101dcd77d7..2413ebde46 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -14,7 +14,6 @@ rules: resources: - services - endpoints - - nodes verbs: - get - list @@ -23,4 +22,9 @@ rules: - patch - delete - create + - apiGroups: [""] + resources: + - nodes + verbs: + - get {{- end }} From 6e52fd319d1c0789fc1f8397d15b87478adafb0f Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 11 Jan 2019 11:22:31 -0800 Subject: [PATCH 124/739] Update consul-k8s version Additionally switches the default NodePort sync to `ExternalFirst` instead of `ExternalOnly`. --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 7e6f5ed9a0..74a45d2161 100644 --- a/values.yaml +++ b/values.yaml @@ -21,7 +21,7 @@ global: # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.3.0" + imageK8S: "hashicorp/consul-k8s:0.4.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running @@ -189,7 +189,7 @@ syncCatalog: # - InternalOnly use's the node's InternalIP address # - ExternalFirst will preferentially use the node's ExternalIP address, but # if it doesn't exist, it will use the node's InternalIP address instead. - nodePortSyncType: ExternalOnly + nodePortSyncType: ExternalFirst # ConnectInject will enable the automatic Connect sidecar injector. connectInject: From 8e5b0f9ba2428cb1dee182b71f3d1624c866a24c Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 11 Jan 2019 15:37:53 -0800 Subject: [PATCH 125/739] Update chart version for release --- Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index ce093daacf..a6cf06f4d3 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.4.0 +version: 0.5.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 3a0ca43a7b2abc3ba1f567cb5615ce186723ff49 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 11 Jan 2019 15:40:25 -0800 Subject: [PATCH 126/739] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f028a76212..c25693ffd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## UNRELEASED +## 0.5.0 (January 11, 2019) + +IMPROVEMENTS: + + * Supports new NodePort syncing style that uses the node ip address + * Adds a configurable tab to the Kubernetes -> Consul sync + ## 0.4.0 (December 7, 2018) IMPROVEMENTS: From 258ee450aff8948beaa2d0384926803ddbddab09 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 22 Jan 2019 16:51:33 -0800 Subject: [PATCH 127/739] Add tests for values added to the chart in 0.5.0 --- test/unit/sync-catalog-deployment.bats | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index f2e40e90c4..0975aeb69d 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -174,6 +174,30 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# k8sTag + +@test "syncCatalog/Deployment: no k8sTag flag by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-k8s-tag"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: can specify k8sTag" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.k8sTag=clusterB' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-k8s-tag=clusterB"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # serviceAccount @@ -186,3 +210,38 @@ load _helpers yq '.spec.template.spec.serviceAccountName | contains("sync-catalog")' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# nodePortSyncType + +@test "syncCatalog/Deployment: nodePortSyncType defaults to ExternalFirst" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-node-port-sync-type=ExternalFirst"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: can set nodePortSyncType to InternalOnly" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.nodePortSyncType=InternalOnly' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-node-port-sync-type=InternalOnly"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: can set nodePortSyncType to ExternalOnly" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.nodePortSyncType=ExternalOnly' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-node-port-sync-type=ExternalOnly"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From f671876857f941c3de142613c35e5d8a9967a016 Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Wed, 16 Jan 2019 16:14:01 -0800 Subject: [PATCH 128/739] Support using an ent binary with license --- .gitignore | 1 + templates/NOTES.txt | 13 +++++++++ templates/_helpers.tpl | 4 +++ templates/client-daemonset.yaml | 3 ++ templates/enterprise-license.yaml | 46 +++++++++++++++++++++++++++++++ templates/secret.yaml | 7 +++++ templates/server-statefulset.yaml | 2 ++ values.yaml | 45 ++++++++++++++++++++++++++---- 8 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 templates/NOTES.txt create mode 100644 templates/enterprise-license.yaml create mode 100644 templates/secret.yaml diff --git a/.gitignore b/.gitignore index f7de6f7f94..45f5d8a947 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ terraform.tfstate* terraform.tfvars values.dev.yaml +*.code-workspace diff --git a/templates/NOTES.txt b/templates/NOTES.txt new file mode 100644 index 0000000000..377cca03c9 --- /dev/null +++ b/templates/NOTES.txt @@ -0,0 +1,13 @@ + +Thank you for installing HashiCorp Consul! + +Now that you have deployed Consul, you should look over the docs on using +Consul with Kubernetes available here: + +https://www.consul.io/docs/platform/k8s/index.html + + +Your release is named {{ .Release.Name }}. To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get {{ .Release.Name }} diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 90a785f83b..bdf9c56b7b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -51,3 +51,7 @@ Add a special case for replicas=1, where it should default to 0 as well. {{- end -}} {{- end -}} {{- end -}} + +{{- define "imagePullSecret" }} +{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" (default .Values.imageCredentials.registry "https://index.docker.io/v1/") (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }} +{{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 4cfd123b2b..7926360859 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -50,6 +50,9 @@ spec: {{- end }} {{- end }} + imagePullSecrets: + - name: {{ .Values.imageCredentials.name }} + containers: - name: consul image: "{{ default .Values.global.image .Values.client.image }}" diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml new file mode 100644 index 0000000000..8996bd71ea --- /dev/null +++ b/templates/enterprise-license.yaml @@ -0,0 +1,46 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-license + labels: + app.kubernetes.io/managed-by: {{.Release.Service | quote }} + app.kubernetes.io/instance: {{.Release.Name | quote }} + helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-license + labels: + app.kubernetes.io/managed-by: {{.Release.Service | quote }} + app.kubernetes.io/instance: {{.Release.Name | quote }} + helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: license + spec: + restartPolicy: Never + + containers: + - name: post-install-job + image: "appropriate/curl" + command: + - "curl" + - "-fsSL" + {{- if .Values.server.license.key }} + - "-X" + - "PUT" + - "http://{{ .Release.Name }}-consul-server:8500/v1/operator/license" + - "--data" + - "{{ .Values.server.license.key }}" + {{- else }} + - "http://{{ .Release.Name }}-consul-server:8500/v1/status/leader" + {{- end }} diff --git a/templates/secret.yaml b/templates/secret.yaml new file mode 100644 index 0000000000..9b6acfa848 --- /dev/null +++ b/templates/secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.imageCredentials.name }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} \ No newline at end of file diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 5eccdacb57..9e466be3d0 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -58,6 +58,8 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} + imagePullSecrets: + - name: {{ .Values.imageCredentials.name }} containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" diff --git a/values.yaml b/values.yaml index 74a45d2161..8652e8a004 100644 --- a/values.yaml +++ b/values.yaml @@ -1,9 +1,5 @@ # Available parameters and their default values for the Consul chart. -# Server, when enabled, configures a server cluster to run. This should -# be disabled if you plan on connecting to a Consul cluster external to -# the Kube cluster. - global: # enabled is the master enabled switch. Setting this to true or false # will enable or disable all the components within this chart by default. @@ -16,7 +12,12 @@ global: # Image is the name (and tag) of the Consul Docker image for clients and # servers below. This can be overridden per component. - image: "consul:1.3.1" + # + # Examples: + # image: "consul:latest" + # image: "consul:1.4.0" + # image: "consul:1.4.0-ent" + image: "tradel/consul-enterprise:1.4.0" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden @@ -29,11 +30,45 @@ global: # currently: https://github.com/hashicorp/consul/issues/1858 datacenter: dc1 +# If you are using a custom Docker image, you may need to provide credentials +# to download the image from a private registry or a private account on +# DockerHub. +# +# Example using Docker Hub: +# registry: https://index.docker.io/v1/ +# username: someone +# password: sillyness +# +# Example using a private registry: +# registry: https://artifactory.example.com/ +# username: someone +# password: sillyness +imageCredentials: + name: consul-registry-key + registry: https://index.docker.io/v1/ + username: someone + password: sillyness + +# Server, when enabled, configures a server cluster to run. This should +# be disabled if you plan on connecting to a Consul cluster external to +# the Kube cluster. + server: enabled: "-" image: null replicas: 3 bootstrapExpect: 3 # Should <= replicas count + replicas: 1 + bootstrapExpect: 1 # Should <= replicas count + + # If you are using an enterprise Consul image, you need to license it, or + # it will stop working in 30 minutes or less. If you paste your license key + # here, it will be applied to your cluster as soon as it elects a leader. + # If you are not using an enterprise image, or if you plan to introduce the + # license key via another route, then set the key to null. + license: + # key: "01MV4U...5EEQJ5HU" + key: null # storage and storageClass are the settings for configuring stateful # storage for the server pods. storage should be set to the disk size of From 4b2d2f5ba7b87628300ee12026f5109a73330518 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 24 Jan 2019 15:23:47 -0800 Subject: [PATCH 129/739] Separate private registry additions from enterprise liscensing Additionally switches the license format to take a Kubernetes secret. Makes the application of the license optional and adds tests for it. --- .gitignore | 1 - templates/_helpers.tpl | 4 --- templates/client-daemonset.yaml | 3 -- templates/enterprise-license.yaml | 24 +++++++------- templates/secret.yaml | 7 ---- templates/server-statefulset.yaml | 2 -- test/unit/enterprise-license.bats | 55 +++++++++++++++++++++++++++++++ values.yaml | 46 +++++++------------------- 8 files changed, 80 insertions(+), 62 deletions(-) delete mode 100644 templates/secret.yaml create mode 100644 test/unit/enterprise-license.bats diff --git a/.gitignore b/.gitignore index 45f5d8a947..f7de6f7f94 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ terraform.tfstate* terraform.tfvars values.dev.yaml -*.code-workspace diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index bdf9c56b7b..90a785f83b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -51,7 +51,3 @@ Add a special case for replicas=1, where it should default to 0 as well. {{- end -}} {{- end -}} {{- end -}} - -{{- define "imagePullSecret" }} -{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" (default .Values.imageCredentials.registry "https://index.docker.io/v1/") (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }} -{{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 7926360859..4cfd123b2b 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -50,9 +50,6 @@ spec: {{- end }} {{- end }} - imagePullSecrets: - - name: {{ .Values.imageCredentials.name }} - containers: - name: consul image: "{{ default .Values.global.image .Values.client.image }}" diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index 8996bd71ea..35478ea1e5 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -1,3 +1,5 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: batch/v1 kind: Job metadata: @@ -32,15 +34,15 @@ spec: containers: - name: post-install-job image: "appropriate/curl" + env: + - name: ENTERPRISE_LICENSE + valueFrom: + secretKeyRef: + name: {{ .Values.server.enterpriseLicense.secretName }} + key: {{ .Values.server.enterpriseLicense.secretKey }} command: - - "curl" - - "-fsSL" - {{- if .Values.server.license.key }} - - "-X" - - "PUT" - - "http://{{ .Release.Name }}-consul-server:8500/v1/operator/license" - - "--data" - - "{{ .Values.server.license.key }}" - {{- else }} - - "http://{{ .Release.Name }}-consul-server:8500/v1/status/leader" - {{- end }} + - | + curl -fsSL -X PUT http://{{ template "consul.fullname" . }}-server:8500/v1/operator/license \ + --data {$ENTERPRISE_LICENSE} +{{- end }} +{{- end }} diff --git a/templates/secret.yaml b/templates/secret.yaml deleted file mode 100644 index 9b6acfa848..0000000000 --- a/templates/secret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: {{ .Values.imageCredentials.name }} -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: {{ template "imagePullSecret" . }} \ No newline at end of file diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 9e466be3d0..5eccdacb57 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -58,8 +58,6 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} - imagePullSecrets: - - name: {{ .Values.imageCredentials.name }} containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" diff --git a/test/unit/enterprise-license.bats b/test/unit/enterprise-license.bats new file mode 100644 index 0000000000..6da9c0892a --- /dev/null +++ b/test/unit/enterprise-license.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/EnterpriseLicense: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/EnterpriseLicense: disabled when servers are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/EnterpriseLicense: disabled when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/EnterpriseLicense: disabled when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/EnterpriseLicense: enabled when secretName and secretKey is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 8652e8a004..f8ebc2043e 100644 --- a/values.yaml +++ b/values.yaml @@ -14,10 +14,9 @@ global: # servers below. This can be overridden per component. # # Examples: - # image: "consul:latest" # image: "consul:1.4.0" - # image: "consul:1.4.0-ent" - image: "tradel/consul-enterprise:1.4.0" + # image: "consul:1.4.0-ent" # Enterprise Consul image + image: "consul:1.3.1" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden @@ -30,45 +29,24 @@ global: # currently: https://github.com/hashicorp/consul/issues/1858 datacenter: dc1 -# If you are using a custom Docker image, you may need to provide credentials -# to download the image from a private registry or a private account on -# DockerHub. -# -# Example using Docker Hub: -# registry: https://index.docker.io/v1/ -# username: someone -# password: sillyness -# -# Example using a private registry: -# registry: https://artifactory.example.com/ -# username: someone -# password: sillyness -imageCredentials: - name: consul-registry-key - registry: https://index.docker.io/v1/ - username: someone - password: sillyness - # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. - server: enabled: "-" image: null replicas: 3 bootstrapExpect: 3 # Should <= replicas count - replicas: 1 - bootstrapExpect: 1 # Should <= replicas count - - # If you are using an enterprise Consul image, you need to license it, or - # it will stop working in 30 minutes or less. If you paste your license key - # here, it will be applied to your cluster as soon as it elects a leader. - # If you are not using an enterprise image, or if you plan to introduce the - # license key via another route, then set the key to null. - license: - # key: "01MV4U...5EEQJ5HU" - key: null + + # enterpriseLicense refers to a Kubernetes secret that you have created that + # contains your enterprise license. It is required if you are using an + # enterprise binary. Defining it here applies it to your cluster once a leader + # has been elected. If you are not using an enterprise image + # or if you plan to introduce the license key via another route, then set + # these fields to null. + enterpriseLicense: + secretName: null + secretKey: null # storage and storageClass are the settings for configuring stateful # storage for the server pods. storage should be set to the disk size of From b1a982433d4fb10d7047b1a56118f1a58adea473 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 6 Feb 2019 16:33:17 -0800 Subject: [PATCH 130/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c25693ffd3..ba21c4c193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## UNRELEASED +IMPROVEMENTS: + + * Supports applying a Consul Enterprise License to the cluster through the Helm chart + ## 0.5.0 (January 11, 2019) IMPROVEMENTS: From bdb78e7a9b3f5419afbec2030042296d6a9fc8ca Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 7 Feb 2019 16:57:19 -0800 Subject: [PATCH 131/739] Update consul.chart definition to not include the version number In Kubernetes, when updating StatefulSets and DaemonSets, only a small number fields are allowed to change. Unfortunately, labels are not included. This means updatint the helm chart, which currently updates the `consul.chart` label will cause errors and interfere with the upgrade. This switches the calculated `consul.chart` value to be a consistent value, which should fix the previously encountered errors when updating. --- templates/_helpers.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 90a785f83b..06292c964c 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -21,7 +21,7 @@ be used as a full name. Create chart name and version as used by the chart label. */}} {{- define "consul.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- printf "%s-helm" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* From e0728b4a349d8a4a1ce61148ec6dec15f5630839 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 7 Feb 2019 17:01:55 -0800 Subject: [PATCH 132/739] Revert "Update consul.chart definition to not include the version number" This reverts commit bdb78e7a9b3f5419afbec2030042296d6a9fc8ca. --- templates/_helpers.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 06292c964c..90a785f83b 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -21,7 +21,7 @@ be used as a full name. Create chart name and version as used by the chart label. */}} {{- define "consul.chart" -}} -{{- printf "%s-helm" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* From f33c8ef4ef2a312d70c13f7648dd796ee557cafa Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 6 Feb 2019 16:20:22 -0800 Subject: [PATCH 133/739] Add a catalog sync acl token configuration option If ACLs are enabled on your Consul cluster, the catalog sync pod requires a valid ACL token to perform its syncing. This allows users to pass a token to the process through a Kubernetes secret. --- templates/sync-catalog-deployment.yaml | 7 +++++ test/unit/sync-catalog-deployment.bats | 37 ++++++++++++++++++++++++++ values.yaml | 7 +++++ 3 files changed, 51 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index bd430c18c3..e809ca6498 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -41,6 +41,13 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- if (and .Values.syncCatalog.aclSyncToken.secretName .Values.syncCatalog.aclSyncToken.secretKey) }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.syncCatalog.aclSyncToken.secretName }} + key: {{ .Values.syncCatalog.aclSyncToken.secretKey }} + {{- end }} command: - "/bin/sh" - "-ec" diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 0975aeb69d..224a0f4d8f 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -245,3 +245,40 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-node-port-sync-type=ExternalOnly"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# aclSyncToken + +@test "syncCatalog/Deployment: aclSyncToken disabled when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.aclSyncToken.secretKey=bar' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: aclSyncToken disabled when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.aclSyncToken.secretName=foo' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: aclSyncToken enabled when secretName and secretKey is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.aclSyncToken.secretName=foo' \ + --set 'syncCatalog.aclSyncToken.secretKey=bar' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index f8ebc2043e..cfe7969078 100644 --- a/values.yaml +++ b/values.yaml @@ -204,6 +204,13 @@ syncCatalog: # if it doesn't exist, it will use the node's InternalIP address instead. nodePortSyncType: ExternalFirst + # aclSyncToken refers to a Kubernetes secret that you have created that contains + # an ACL token for your Consul cluster which allows the sync process the correct + # permissions. This is only needed if ACLs are enabled on the Consul cluster. + aclSyncToken: + secretName: null + secretKey: null + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false From 325749e5c35514d93a2a7e2f9072f6ee46031b1c Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 7 Feb 2019 17:19:50 -0800 Subject: [PATCH 134/739] Update CHANGELOG.md --- CHANGELOG.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba21c4c193..83368fd885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * Supports applying a Consul Enterprise License to the cluster through the Helm chart + * Support assigning an ACL token to the catalog sync process [[GH 26](https://github.com/hashicorp/consul-k8s/issues/26)] ## 0.5.0 (January 11, 2019) @@ -16,28 +17,28 @@ IMPROVEMENTS: IMPROVEMENTS: * RBAC support for `syncCatalog`. This will create the `ClusterRole`, `ClusterRoleBinding` - and `ServiceAccount` that is necessary for the catalog sync. [GH-29] - * client: agents now have the node name set to the actual K8S node name [GH-14] + and `ServiceAccount` that is necessary for the catalog sync. [[GH-20](https://github.com/hashicorp/consul-helm/issues/20)] + * client: agents now have the node name set to the actual K8S node name [[GH-14](https://github.com/hashicorp/consul-helm/issues/14)] * RBAC support for `connectInject`. This will create a `ClusterRole`, `ClusterRoleBinding`, and `ServiceAccount` that is necessary for the connect injector to automatically generate TLS certificates to interact with the Kubernetes API. * Server affinity is now configurable. This makes it easier to run an entire - Consul cluster on Minikube. [GH-13] + Consul cluster on Minikube. [[GH-13](https://github.com/hashicorp/consul-helm/issues/13)] * Liveness probes are now http calls, reducing errors in the logs. * All namespaced resources now specify the namespace metadata, making `helm template` usage in - a non-default namespace easier. [GH-66] + a non-default namespace easier. [[GH-66](https://github.com/hashicorp/consul-helm/issues/66)] * Add support for ClusterIP service syncing. BUG FIXES: * Add catalog sync default behavior flag to the chart [GH-28] * Updated images to point to latest versions for 0.3.0. - * Add missing continuation characters to long commands [GH-26]. + * Add missing continuation characters to long commands [[GH-26](https://github.com/hashicorp/consul-helm/issues/26)]. * connectInject: set the correct namespace for the MutatingWebhookConfiguration - so that deployments work in non-default namespaces. [GH-41] - * Provide a valid `maxUnavailable` value when replicas=1. [GH-58] + so that deployments work in non-default namespaces. [[GH-38](https://github.com/hashicorp/consul-helm/issues/38)] + * Provide a valid `maxUnavailable` value when replicas=1. [[GH-58](https://github.com/hashicorp/consul-helm/issues/58)] * Correctly sets server resource requirements. - * Update the `maxUnavailable` default calculation to allow rolling updates on 3 server clusters. [GH-71] + * Update the `maxUnavailable` default calculation to allow rolling updates on 3 server clusters. [[GH-71](https://github.com/hashicorp/consul-helm/issues/71)] ## 0.3.0 (October 11, 2018) @@ -54,7 +55,7 @@ FEATURES: IMPROVEMENTS: - * server: support `storageClass` [GH-7] + * server: support `storageClass` [[GH-7](https://github.com/hashicorp/consul-helm/issues/7)] ## 0.1.0 From 05e67b856ecab00681fe492f2cd8853e0853c073 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 7 Feb 2019 16:57:19 -0800 Subject: [PATCH 135/739] Update consul.chart definition to not include the version number In Kubernetes, when updating StatefulSets and DaemonSets, only a small number fields are allowed to change. Unfortunately, labels are not included. This means updatint the helm chart, which currently updates the `consul.chart` label will cause errors and interfere with the upgrade. This switches the calculated `consul.chart` value to be a consistent value, which should fix the previously encountered errors when updating. --- templates/_helpers.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 90a785f83b..06292c964c 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -21,7 +21,7 @@ be used as a full name. Create chart name and version as used by the chart label. */}} {{- define "consul.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- printf "%s-helm" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* From 13e90c199bec2e85b7d9afa47b803dc4b222bac3 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 8 Feb 2019 12:22:03 -0800 Subject: [PATCH 136/739] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83368fd885..ac8485527f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,11 @@ IMPROVEMENTS: * Supports applying a Consul Enterprise License to the cluster through the Helm chart - * Support assigning an ACL token to the catalog sync process [[GH 26](https://github.com/hashicorp/consul-k8s/issues/26)] + * Support assigning an ACL token to the catalog sync process [[GH 26](https://github.com/hashicorp/consul-k8s/issues/26)] + +BUG FIXES: + + * Switch the chart labels to a non-changing value to allow helm upgrades [[GH 86](https://github.com/hashicorp/consul-helm/issues/86)] ## 0.5.0 (January 11, 2019) From a278ad2ff9746943eb74150e869fef263724057d Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 8 Feb 2019 14:09:27 -0800 Subject: [PATCH 137/739] Update consul and consul-k8s default versions --- values.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/values.yaml b/values.yaml index cfe7969078..788e8dc24d 100644 --- a/values.yaml +++ b/values.yaml @@ -14,14 +14,14 @@ global: # servers below. This can be overridden per component. # # Examples: - # image: "consul:1.4.0" - # image: "consul:1.4.0-ent" # Enterprise Consul image - image: "consul:1.3.1" + # image: "consul:1.4.2" + # image: "consul:1.4.2-ent" # Enterprise Consul image + image: "consul:1.4.2" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.4.0" + imageK8S: "hashicorp/consul-k8s:0.5.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 75108b5f87e4eed16bcaeca75131223679b3a358 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 8 Feb 2019 15:23:49 -0800 Subject: [PATCH 138/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac8485527f..e7af7a79e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ IMPROVEMENTS: * Supports applying a Consul Enterprise License to the cluster through the Helm chart * Support assigning an ACL token to the catalog sync process [[GH 26](https://github.com/hashicorp/consul-k8s/issues/26)] + * Updates default `consul` version to `1.4.2` and `consul-k8s` version to `0.5.0` BUG FIXES: From fdacca815c6a027425952595639107dcd6d3e307 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 8 Feb 2019 14:15:39 -0800 Subject: [PATCH 139/739] Update Chart.yaml version to 0.6.0 --- Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index a6cf06f4d3..c6d59c9842 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.5.0 +version: 0.6.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 8f80f44fba12d8d0f4de72ebba389c4d770e6f95 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 8 Feb 2019 15:28:06 -0800 Subject: [PATCH 140/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7af7a79e4..658849a1f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## UNRELEASED +## 0.6.0 (February 8, 2019) + IMPROVEMENTS: * Supports applying a Consul Enterprise License to the cluster through the Helm chart From ec736e085e742951e432c345b7632bfda046cc73 Mon Sep 17 00:00:00 2001 From: Artem Kajalainen Date: Wed, 2 Jan 2019 11:49:39 +0200 Subject: [PATCH 141/739] feat: add option to assign priorityClassName for client and server pods Signed-off-by: Artem Kajalainen --- templates/client-daemonset.yaml | 4 ++++ templates/server-statefulset.yaml | 3 +++ values.yaml | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 4cfd123b2b..dc6eb390a6 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -31,6 +31,10 @@ spec: spec: terminationGracePeriodSeconds: 10 + {{- if .Values.client.priorityClassName }} + priorityClassName: "{{ .Values.client.priorityClassName }}" + {{- end }} + # Consul agents require a directory for data, even clients. The data # is okay to be wiped though if the Pod is removed, so just use an # emptyDir volume. diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 5eccdacb57..e983db7762 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -58,6 +58,9 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} + {{- if .Values.server.priorityClassName }} + priorityClassName: "{{ .Values.server.priorityClassName }}" + {{- end }} containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" diff --git a/values.yaml b/values.yaml index 788e8dc24d..e1831b83cb 100644 --- a/values.yaml +++ b/values.yaml @@ -106,6 +106,10 @@ server: component: server topologyKey: kubernetes.io/hostname + # used to assign priority to server pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. @@ -137,6 +141,10 @@ client: # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul + # used to assign priority to client pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From d797ba637b8213a024aa25f2196be4157ba65607 Mon Sep 17 00:00:00 2001 From: Artem Kajalainen Date: Mon, 18 Feb 2019 09:39:40 +0200 Subject: [PATCH 142/739] fix: use quote function instead of quotes Signed-off-by: Artem Kajalainen --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index dc6eb390a6..012a355318 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -32,7 +32,7 @@ spec: terminationGracePeriodSeconds: 10 {{- if .Values.client.priorityClassName }} - priorityClassName: "{{ .Values.client.priorityClassName }}" + priorityClassName: {{ .Values.client.priorityClassName | quote }} {{- end }} # Consul agents require a directory for data, even clients. The data diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index e983db7762..032cc560bb 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -59,7 +59,7 @@ spec: {{- end }} {{- end }} {{- if .Values.server.priorityClassName }} - priorityClassName: "{{ .Values.server.priorityClassName }}" + priorityClassName: {{ .Values.server.priorityClassName | quote }} {{- end }} containers: - name: consul From e516f5d802cd2836bb5f7035c707dda59290fe33 Mon Sep 17 00:00:00 2001 From: Artem Kajalainen Date: Mon, 18 Feb 2019 09:40:12 +0200 Subject: [PATCH 143/739] feat(tests): add unit tests for priorityClassName option Signed-off-by: Artem Kajalainen --- test/unit/client-daemonset.bats | 22 ++++++++++++++++++++++ test/unit/server-statefulset.bats | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 9544d55ff3..cfb53d45be 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -220,3 +220,25 @@ load _helpers yq -r '.spec.template.spec.containers[0].command | map(select(test("/consul/userconfig/foo"))) | length' | tee /dev/stderr) [ "${actual}" = "1" ] } + +#-------------------------------------------------------------------- +# priorityClassName + +@test "client/DaemonSet: priorityClassName is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/DaemonSet: specified priorityClassName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.priorityClassName=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index db1a31cbcd..071543a1de 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -265,3 +265,26 @@ load _helpers yq '.spec.template.spec.affinity | .podAntiAffinity? != null' | tee /dev/stderr) [ "${actual}" = "true" ] } + + +#-------------------------------------------------------------------- +# priorityClassName + +@test "server/StatefulSet: priorityClassName is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/StatefulSet: specified priorityClassName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.priorityClassName=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} From 4254c34c2f92a16183cf059670965b7727dbd506 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 27 Feb 2019 11:41:39 -0800 Subject: [PATCH 144/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 658849a1f4..a4b64bbf8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## UNRELEASED +IMPROVEMENTS: + + * Support pod priority classes for Consul servers and clients + ## 0.6.0 (February 8, 2019) IMPROVEMENTS: From 9934fe9f0896890dc2aec40cc5ebab6d5b3969d6 Mon Sep 17 00:00:00 2001 From: Yong Wen Chua Date: Fri, 25 Jan 2019 13:52:53 +0800 Subject: [PATCH 145/739] Add additional configuration options for UI Service --- templates/ui-service.yaml | 13 +++++++----- test/unit/ui-service.bats | 44 +++++++++++++++++++++++++++++++++++++++ values.yaml | 7 +++++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index 55fb4abd5e..fc265d0b35 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -1,8 +1,4 @@ -# Headless service for Consul server DNS entries. This service should only -# point to Consul servers. For access to an agent, one should assume that -# the agent is installed locally on the node and the NODE_IP should be used. -# If the node can't run a Consul agent, then this service can be used to -# communicate directly to a server agent. +# UI Service for Consul Server {{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: v1 kind: Service @@ -14,6 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + {{- if .Values.ui.service.annotations }} + annotations: + {{ tpl .Values.ui.service.annotations . | nindent 4 | trim }} + {{- end }} spec: selector: app: {{ template "consul.name" . }} @@ -26,4 +26,7 @@ spec: {{- if .Values.ui.service.type }} type: {{ .Values.ui.service.type }} {{- end }} + {{- if .Values.ui.service.additionalSpec }} + {{ tpl .Values.ui.service.additionalSpec . | nindent 2 | trim }} + {{- end }} {{- end }} diff --git a/test/unit/ui-service.bats b/test/unit/ui-service.bats index df46864418..f369e03168 100755 --- a/test/unit/ui-service.bats +++ b/test/unit/ui-service.bats @@ -92,3 +92,47 @@ load _helpers yq -r '.spec.type' | tee /dev/stderr) [ "${actual}" = "LoadBalancer" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "ui/Service: no annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.metadata.annotations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ui/Service: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + +#-------------------------------------------------------------------- +# additionalSpec + +@test "ui/Service: no additionalSpec by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.loadBalancerIP' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ui/Service: additionalSpec can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.additionalSpec=loadBalancerIP: 1.2.3.4' \ + . | tee /dev/stderr | + yq -r '.spec.loadBalancerIP' | tee /dev/stderr) + [ "${actual}" = "1.2.3.4" ] +} diff --git a/values.yaml b/values.yaml index e1831b83cb..72c0606483 100644 --- a/values.yaml +++ b/values.yaml @@ -169,6 +169,13 @@ ui: service: enabled: true type: null + # This should be a multi-line string mapping directly to the a map of + # the annotations to apply to the UI service + annotations: null + # Additional ServiceSpec values + # This should be a multi-line string mapping directly to a Kubernetes + # ServiceSpec object. + additionalSpec: null # syncCatalog will run the catalog sync process to sync K8S with Consul # services. This can run bidirectional (default) or unidirectionally (Consul From 7ea671f8328b1e1d4f2c3efdfebfadc085d8d4b1 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 27 Feb 2019 15:05:13 -0800 Subject: [PATCH 146/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4b64bbf8e..84578e4d59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * Support pod priority classes for Consul servers and clients + * Add annotation and additional spec values for the UI service ## 0.6.0 (February 8, 2019) From e3e47a44ec6c8eb11a8eabbb02516e6daa698fd7 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 12 Feb 2019 16:10:49 -0800 Subject: [PATCH 147/739] Add liveness and readiness probes for the catalog sync pod With the additional of a `/health/ready` endpoint in the latest version of consul-k8s, it's possible to add healthchecks to this pod, allowing Kubernetes to restart it if it has any issues. Updates consul-k8s default image to v0.6.0 which supports these checks. Adds note about removing these checks if using an older version. --- templates/sync-catalog-deployment.yaml | 20 ++++++++++++++++++++ values.yaml | 5 ++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index e809ca6498..bed6f39d99 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -75,4 +75,24 @@ spec: {{- if .Values.syncCatalog.k8sTag }} -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} {{- end }} + livenessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + failureThreshold: 5 + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 {{- end }} diff --git a/values.yaml b/values.yaml index 72c0606483..416745f078 100644 --- a/values.yaml +++ b/values.yaml @@ -21,7 +21,10 @@ global: # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden # per component below. - imageK8S: "hashicorp/consul-k8s:0.5.0" + # Note: support for the catalog sync's liveness and readiness probes was added + # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to + # remove these checks to make the sync work. + imageK8S: "hashicorp/consul-k8s:0.6.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From b3bfbf5c78b4da896cfe68edbd61240a91d64b7f Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 28 Feb 2019 10:40:20 -0800 Subject: [PATCH 148/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84578e4d59..17a263b236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ IMPROVEMENTS: * Support pod priority classes for Consul servers and clients * Add annotation and additional spec values for the UI service + * Add liveness and readiness checks to the catalog sync pod [[consul-k8s GH 57](https://github.com/hashicorp/consul-k8s/issues/57)] ## 0.6.0 (February 8, 2019) From ecb1f24ff633381b90abc49bf8afaeab2f41fe23 Mon Sep 17 00:00:00 2001 From: Emilien Kenler Date: Mon, 18 Feb 2019 15:14:47 +0900 Subject: [PATCH 149/739] Allow to specify custom annotations --- templates/client-daemonset.yaml | 3 +++ templates/server-statefulset.yaml | 3 +++ values.yaml | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 012a355318..fc8348fff9 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -28,6 +28,9 @@ spec: hasDNS: "true" annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.client.annotations }} +{{ toYaml .Values.client.annotations | indent 8 }} + {{- end }} spec: terminationGracePeriodSeconds: 10 diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 032cc560bb..6a04290190 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -37,6 +37,9 @@ spec: hasDNS: "true" annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.server.annotations }} +{{ toYaml .Values.server.annotations | indent 8 }} + {{- end }} spec: {{- if .Values.server.affinity }} affinity: diff --git a/values.yaml b/values.yaml index 416745f078..1f846843b3 100644 --- a/values.yaml +++ b/values.yaml @@ -112,6 +112,9 @@ server: # used to assign priority to server pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" + + # Extra annotations to attach to the server pods + annotations: {} # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional @@ -147,6 +150,9 @@ client: # used to assign priority to client pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" + + # Extra annotations to attach to the client pods + annotations: {} # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) From 2c9a412b29fb7a1d6e36b83d338e9c318f8d3533 Mon Sep 17 00:00:00 2001 From: Emilien Kenler Date: Mon, 25 Feb 2019 14:51:09 +0900 Subject: [PATCH 150/739] Use nindent instead of indent --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index fc8348fff9..54d91d7d41 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -29,7 +29,7 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" {{- if .Values.client.annotations }} -{{ toYaml .Values.client.annotations | indent 8 }} + {{- toYaml .Values.client.annotations | nindent 8 }} {{- end }} spec: terminationGracePeriodSeconds: 10 diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 6a04290190..1d765f5564 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -38,7 +38,7 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" {{- if .Values.server.annotations }} -{{ toYaml .Values.server.annotations | indent 8 }} + {{- toYaml .Values.server.annotations | nindent 8 }} {{- end }} spec: {{- if .Values.server.affinity }} From 3eefb75264266bcaedaadc2fac78b5ae72feea77 Mon Sep 17 00:00:00 2001 From: Emilien Kenler Date: Mon, 25 Feb 2019 16:27:20 +0900 Subject: [PATCH 151/739] Add tests for custom annotations --- test/unit/client-daemonset.bats | 22 ++++++++++++++++++++++ test/unit/server-statefulset.bats | 22 ++++++++++++++++++++++ values.yaml | 4 ++-- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index cfb53d45be..90eaa59e49 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -242,3 +242,25 @@ load _helpers yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) [ "${actual}" = "testing" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "client/DaemonSet: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "client/DaemonSet: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 071543a1de..cb77a29412 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -288,3 +288,25 @@ load _helpers yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) [ "${actual}" = "testing" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "server/StatefulSet: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "server/StatefulSet: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.annotations.foo=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/values.yaml b/values.yaml index 1f846843b3..298bf36f2e 100644 --- a/values.yaml +++ b/values.yaml @@ -112,7 +112,7 @@ server: # used to assign priority to server pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" - + # Extra annotations to attach to the server pods annotations: {} @@ -150,7 +150,7 @@ client: # used to assign priority to client pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" - + # Extra annotations to attach to the client pods annotations: {} From ae0612ccebb9bdcae6a2da1c5afa0b69be6ae037 Mon Sep 17 00:00:00 2001 From: Emilien Kenler Date: Thu, 28 Feb 2019 09:56:03 +0900 Subject: [PATCH 152/739] Pass annotations as multi-line strings --- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 2 +- test/unit/server-statefulset.bats | 2 +- values.yaml | 8 ++++++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 54d91d7d41..f0e8cd0e6d 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -29,7 +29,7 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" {{- if .Values.client.annotations }} - {{- toYaml .Values.client.annotations | nindent 8 }} + {{- tpl .Values.client.annotations . | nindent 8 }} {{- end }} spec: terminationGracePeriodSeconds: 10 diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 1d765f5564..bdc7809c4b 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -38,7 +38,7 @@ spec: annotations: "consul.hashicorp.com/connect-inject": "false" {{- if .Values.server.annotations }} - {{- toYaml .Values.server.annotations | nindent 8 }} + {{- tpl .Values.server.annotations . | nindent 8 }} {{- end }} spec: {{- if .Values.server.affinity }} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index cb77a29412..2e842a62e1 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -305,7 +305,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'server.annotations.foo=bar' \ + --set 'server.annotations=foo: bar' \ . | tee /dev/stderr | yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] diff --git a/values.yaml b/values.yaml index 298bf36f2e..5bb29e1e5b 100644 --- a/values.yaml +++ b/values.yaml @@ -114,7 +114,9 @@ server: priorityClassName: "" # Extra annotations to attach to the server pods - annotations: {} + # This should be a multi-line string mapping directly to the a map of + # the annotations to apply to the server pods + annotations: null # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional @@ -152,7 +154,9 @@ client: priorityClassName: "" # Extra annotations to attach to the client pods - annotations: {} + # This should be a multi-line string mapping directly to the a map of + # the annotations to apply to the client pods + annotations: null # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) From 10156c91d67406b819240db4118b8b19cbcbf2aa Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 1 Mar 2019 10:33:32 -0800 Subject: [PATCH 153/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a263b236..0f955aedc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ IMPROVEMENTS: * Support pod priority classes for Consul servers and clients * Add annotation and additional spec values for the UI service * Add liveness and readiness checks to the catalog sync pod [[consul-k8s GH 57](https://github.com/hashicorp/consul-k8s/issues/57)] + * Support custom annotations for Consul clients and servers ## 0.6.0 (February 8, 2019) From b406e0fd34fa233ba5d4fa9b4cd421f9ec1d8710 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 4 Mar 2019 16:44:34 -0800 Subject: [PATCH 154/739] Update readme to include info about the repo's merge strategy --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 80686d025d..694627ee97 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,18 @@ Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the [Consul website](https://www.consul.io/docs/platform/k8s/helm.html). +## Rebasing contributions against master + +PRs in this repo are merged using the [`rebase`](https://git-scm.com/docs/git-rebase) method. This keeps +the git history clean by adding the PR commits to the most recent end of the commit history. It also has +the benefit of keeping all the relevant commits for a given PR together, rather than spread throughout the +git history based on when the commits were first created. + +If the changes in your PR do not conflict with any of the existing code in the project, then Github supports +automatic rebasing when the PR is accepted into the code. However, if there are conflicts (there will be +a warning on the PR that reads "This branch cannot be rebased due to conflicts"), you will need to manually +rebase the branch on master, fixing any conflicts along the way before the code can be merged. + ## Testing The Helm chart ships with both unit and acceptance tests. From 609dc4ecfa322fe87a7294e3b1d0a3c95de7e44f Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Fri, 8 Mar 2019 10:18:14 -0500 Subject: [PATCH 155/739] Escaping shell command for ent license --- templates/enterprise-license.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index 35478ea1e5..557b6fe644 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -41,6 +41,8 @@ spec: name: {{ .Values.server.enterpriseLicense.secretName }} key: {{ .Values.server.enterpriseLicense.secretKey }} command: + - "/bin/sh" + - "-ec" - | curl -fsSL -X PUT http://{{ template "consul.fullname" . }}-server:8500/v1/operator/license \ --data {$ENTERPRISE_LICENSE} From 58fb7ac137d1fd91bfd4c60e2459add8cbd0fd23 Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Fri, 8 Mar 2019 11:14:06 -0500 Subject: [PATCH 156/739] Fixed variable syntax in shell command --- templates/enterprise-license.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index 557b6fe644..8616a396d3 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -45,6 +45,6 @@ spec: - "-ec" - | curl -fsSL -X PUT http://{{ template "consul.fullname" . }}-server:8500/v1/operator/license \ - --data {$ENTERPRISE_LICENSE} + --data ${ENTERPRISE_LICENSE} {{- end }} {{- end }} From 482a7642afcfde4de5091a847adf90b0f7520333 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 5 Mar 2019 16:20:41 -0800 Subject: [PATCH 157/739] Remove quotes from `extraConfig` inputs This enables users to specify `extraConfig` values using Helm's `--set` CLI flag while installing the Helm chart. The format for using this command is: ``` --set 'client.extraConfig="{"log_level": "DEBUG"}"' ``` If client or server `extraConfig` values are specified in values.yaml, this change will generally not impact the values as they are already strings without the addition of quotes. --- templates/client-config-configmap.yaml | 2 +- templates/server-config-configmap.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/client-config-configmap.yaml b/templates/client-config-configmap.yaml index 9d2ddc57d2..001158982e 100644 --- a/templates/client-config-configmap.yaml +++ b/templates/client-config-configmap.yaml @@ -13,5 +13,5 @@ metadata: release: {{ .Release.Name }} data: extra-from-values.json: |- -{{ tpl .Values.client.extraConfig . | indent 4 }} +{{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }} {{- end }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 79171c1e7a..b0f9ea198d 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -12,5 +12,5 @@ metadata: release: {{ .Release.Name }} data: extra-from-values.json: |- -{{ tpl .Values.server.extraConfig . | indent 4 }} +{{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} {{- end }} From e2bbe60105a71294391043a7eee214e43f5c01c0 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 11 Mar 2019 12:01:49 -0700 Subject: [PATCH 158/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f955aedc5..85a8caab69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ IMPROVEMENTS: * Add annotation and additional spec values for the UI service * Add liveness and readiness checks to the catalog sync pod [[consul-k8s GH 57](https://github.com/hashicorp/consul-k8s/issues/57)] * Support custom annotations for Consul clients and servers + +BUG FIXES: + + * Allow setting `extraConfig` variables using Helm's `--set` flag [[GH 74](https://github.com/hashicorp/consul-helm/issues/74)] ## 0.6.0 (February 8, 2019) From bd441506988690028c38e49b4181d47ddf55dff9 Mon Sep 17 00:00:00 2001 From: Liviu Damian Date: Tue, 30 Oct 2018 09:53:08 +0200 Subject: [PATCH 159/739] Added PodSecurityPolicies --- templates/client-clusterrole.yaml | 20 +++++++++ templates/client-clusterrolebinding.yaml | 19 ++++++++ templates/client-daemonset.yaml | 3 ++ templates/client-podsecuritypolicy.yaml | 43 +++++++++++++++++++ templates/client-serviceaccount.yaml | 12 ++++++ templates/connect-inject-clusterrole.yaml | 8 ++++ templates/connect-inject-deployment.yaml | 1 + .../connect-inject-podsecuritypolicy.yaml | 40 +++++++++++++++++ templates/server-clusterrole.yaml | 20 +++++++++ templates/server-clusterrolebinding.yaml | 19 ++++++++ templates/server-podsecuritypolicy.yaml | 41 ++++++++++++++++++ templates/server-serviceaccount.yaml | 12 ++++++ templates/server-statefulset.yaml | 2 + templates/sync-catalog-cluster-role.yaml | 7 +++ templates/sync-catalog-podsecuritypolicy.yaml | 40 +++++++++++++++++ 15 files changed, 287 insertions(+) create mode 100644 templates/client-clusterrole.yaml create mode 100644 templates/client-clusterrolebinding.yaml create mode 100644 templates/client-podsecuritypolicy.yaml create mode 100644 templates/client-serviceaccount.yaml create mode 100644 templates/connect-inject-podsecuritypolicy.yaml create mode 100644 templates/server-clusterrole.yaml create mode 100644 templates/server-clusterrolebinding.yaml create mode 100644 templates/server-podsecuritypolicy.yaml create mode 100644 templates/server-serviceaccount.yaml create mode 100644 templates/sync-catalog-podsecuritypolicy.yaml diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml new file mode 100644 index 0000000000..f8deef450b --- /dev/null +++ b/templates/client-clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: +- apiGroups: + - policy + resources: + - podsecuritypolicies + resourceNames: + - {{ template "consul.fullname" . }} + verbs: + - use +{{- end }} diff --git a/templates/client-clusterrolebinding.yaml b/templates/client-clusterrolebinding.yaml new file mode 100644 index 0000000000..3034ae7697 --- /dev/null +++ b/templates/client-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index f0e8cd0e6d..fb3fd320cd 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -33,6 +33,9 @@ spec: {{- end }} spec: terminationGracePeriodSeconds: 10 + serviceAccount: {{ template "consul.fullname" . }} + serviceAccountName: {{ template "consul.fullname" . }} + securityContext: {} {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml new file mode 100644 index 0000000000..8f7054897b --- /dev/null +++ b/templates/client-podsecuritypolicy.yaml @@ -0,0 +1,43 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostPorts: + - min: 8500 + max: 8502 + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/templates/client-serviceaccount.yaml b/templates/client-serviceaccount.yaml new file mode 100644 index 0000000000..8f0b22a4bc --- /dev/null +++ b/templates/client-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index a873c680db..237ad33143 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -17,4 +17,12 @@ rules: - "list" - "watch" - "patch" +- apiGroups: + - policy + resources: + - podsecuritypolicies + resourcesName: + - {{ template "consul.fullname" . }}-connect-injector-webhook + verbs: + - use {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 3564e128a9..28313408cd 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -26,6 +26,7 @@ spec: release: {{ .Release.Name }} component: connect-injector spec: + securityContext: {} {{- if not .Values.connectInject.certs.secretName }} serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account {{- end }} diff --git a/templates/connect-inject-podsecuritypolicy.yaml b/templates/connect-inject-podsecuritypolicy.yaml new file mode 100644 index 0000000000..7243d5ce1a --- /dev/null +++ b/templates/connect-inject-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-webhook-deployment + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/templates/server-clusterrole.yaml b/templates/server-clusterrole.yaml new file mode 100644 index 0000000000..5ef0eed66d --- /dev/null +++ b/templates/server-clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: +- apiGroups: + - policy + resources: + - podsecuritypolicies + resourceNames: + - {{ template "consul.fullname" . }}-server + verbs: + - use +{{- end }} diff --git a/templates/server-clusterrolebinding.yaml b/templates/server-clusterrolebinding.yaml new file mode 100644 index 0000000000..0e3010f4cd --- /dev/null +++ b/templates/server-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-server +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/templates/server-podsecuritypolicy.yaml b/templates/server-podsecuritypolicy.yaml new file mode 100644 index 0000000000..ded4e82fc2 --- /dev/null +++ b/templates/server-podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/templates/server-serviceaccount.yaml b/templates/server-serviceaccount.yaml new file mode 100644 index 0000000000..0b35ac4e95 --- /dev/null +++ b/templates/server-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index bdc7809c4b..2dbd3d06b4 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -46,6 +46,8 @@ spec: {{ tpl .Values.server.affinity . | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: 10 + serviceAccount: {{ template "consul.fullname" . }}-server + serviceAccountName: {{ template "consul.fullname" . }}-server securityContext: fsGroup: 1000 volumes: diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml index 2413ebde46..5a0fa09889 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -27,4 +27,11 @@ rules: - nodes verbs: - get + - apiGroups: ["policy"] + resources: + - podsecuritypolicies + resourceNames: + - {{ template "consul.fullname" . }}-sync-catalog + verbs: + - use {{- end }} diff --git a/templates/sync-catalog-podsecuritypolicy.yaml b/templates/sync-catalog-podsecuritypolicy.yaml new file mode 100644 index 0000000000..47d2d4f1cd --- /dev/null +++ b/templates/sync-catalog-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} From a7721c2f68f0fc848e26b58ae4ad79a729672078 Mon Sep 17 00:00:00 2001 From: Liviu Damian Date: Fri, 30 Nov 2018 14:40:38 +0200 Subject: [PATCH 160/739] Implement PR suggestions --- templates/client-clusterrole.yaml | 4 ++-- templates/client-clusterrolebinding.yaml | 6 +++--- templates/client-daemonset.yaml | 4 +--- templates/client-podsecuritypolicy.yaml | 2 +- templates/client-serviceaccount.yaml | 2 +- templates/connect-inject-deployment.yaml | 1 - templates/connect-inject-podsecuritypolicy.yaml | 2 +- templates/server-statefulset.yaml | 1 - 8 files changed, 9 insertions(+), 13 deletions(-) diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index f8deef450b..f16fcb4d69 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -14,7 +14,7 @@ rules: resources: - podsecuritypolicies resourceNames: - - {{ template "consul.fullname" . }} + - {{ template "consul.fullname" . }}-client verbs: - use {{- end }} diff --git a/templates/client-clusterrolebinding.yaml b/templates/client-clusterrolebinding.yaml index 3034ae7697..e1061660dc 100644 --- a/templates/client-clusterrolebinding.yaml +++ b/templates/client-clusterrolebinding.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -11,9 +11,9 @@ metadata: roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client subjects: - kind: ServiceAccount - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client namespace: {{ .Release.Namespace }} {{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index fb3fd320cd..f15ec38cf3 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -33,9 +33,7 @@ spec: {{- end }} spec: terminationGracePeriodSeconds: 10 - serviceAccount: {{ template "consul.fullname" . }} - serviceAccountName: {{ template "consul.fullname" . }} - securityContext: {} + serviceAccountName: {{ template "consul.fullname" . }}-client {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 8f7054897b..4355509686 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -2,7 +2,7 @@ apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/client-serviceaccount.yaml b/templates/client-serviceaccount.yaml index 8f0b22a4bc..dacdf8f2b7 100644 --- a/templates/client-serviceaccount.yaml +++ b/templates/client-serviceaccount.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{ template "consul.fullname" . }} + name: {{ template "consul.fullname" . }}-client namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 28313408cd..3564e128a9 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -26,7 +26,6 @@ spec: release: {{ .Release.Name }} component: connect-injector spec: - securityContext: {} {{- if not .Values.connectInject.certs.secretName }} serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account {{- end }} diff --git a/templates/connect-inject-podsecuritypolicy.yaml b/templates/connect-inject-podsecuritypolicy.yaml index 7243d5ce1a..7a0b9f7d01 100644 --- a/templates/connect-inject-podsecuritypolicy.yaml +++ b/templates/connect-inject-podsecuritypolicy.yaml @@ -2,7 +2,7 @@ apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: - name: {{ template "consul.fullname" . }}-connect-injector-webhook-deployment + name: {{ template "consul.fullname" . }}-connect-injector-webhook labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 2dbd3d06b4..a3b03c1adf 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -46,7 +46,6 @@ spec: {{ tpl .Values.server.affinity . | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: 10 - serviceAccount: {{ template "consul.fullname" . }}-server serviceAccountName: {{ template "consul.fullname" . }}-server securityContext: fsGroup: 1000 From 4961d1768d9ea20e05b68499d4a87411c61b2569 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 6 Dec 2018 13:24:42 -0800 Subject: [PATCH 161/739] Add global variable for enabling pod security policies Adds `enablePodSecurityPolicies` to the global section of the values file. Makes the pod security policies and the cluster role modifications for this trigger off of this variable. --- templates/client-clusterrole.yaml | 8 ++++---- templates/client-podsecuritypolicy.yaml | 2 +- templates/connect-inject-clusterrole.yaml | 8 ++++---- templates/connect-inject-podsecuritypolicy.yaml | 2 +- templates/server-clusterrole.yaml | 8 ++++---- templates/server-podsecuritypolicy.yaml | 2 +- templates/sync-catalog-cluster-role.yaml | 4 ++++ templates/sync-catalog-podsecuritypolicy.yaml | 2 +- values.yaml | 5 +++++ 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index f16fcb4d69..e4f210e592 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -9,12 +9,12 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} rules: -- apiGroups: - - policy - resources: - - podsecuritypolicies +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] resourceNames: - {{ template "consul.fullname" . }}-client verbs: - use {{- end }} +{{- end }} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 4355509686..da9d0b1632 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -1,4 +1,4 @@ -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 237ad33143..32029d6b1f 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -17,12 +17,12 @@ rules: - "list" - "watch" - "patch" -- apiGroups: - - policy - resources: - - podsecuritypolicies +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] resourcesName: - {{ template "consul.fullname" . }}-connect-injector-webhook verbs: - use {{- end }} +{{- end }} diff --git a/templates/connect-inject-podsecuritypolicy.yaml b/templates/connect-inject-podsecuritypolicy.yaml index 7a0b9f7d01..b1fee54cc8 100644 --- a/templates/connect-inject-podsecuritypolicy.yaml +++ b/templates/connect-inject-podsecuritypolicy.yaml @@ -1,4 +1,4 @@ -{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: diff --git a/templates/server-clusterrole.yaml b/templates/server-clusterrole.yaml index 5ef0eed66d..ae8a2d7903 100644 --- a/templates/server-clusterrole.yaml +++ b/templates/server-clusterrole.yaml @@ -9,12 +9,12 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} rules: -- apiGroups: - - policy - resources: - - podsecuritypolicies +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] resourceNames: - {{ template "consul.fullname" . }}-server verbs: - use {{- end }} +{{- end }} diff --git a/templates/server-podsecuritypolicy.yaml b/templates/server-podsecuritypolicy.yaml index ded4e82fc2..ef8ecfdb93 100644 --- a/templates/server-podsecuritypolicy.yaml +++ b/templates/server-podsecuritypolicy.yaml @@ -1,4 +1,4 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-cluster-role.yaml index 5a0fa09889..676ef44d19 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-cluster-role.yaml @@ -30,8 +30,12 @@ rules: - apiGroups: ["policy"] resources: - podsecuritypolicies +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] resourceNames: - {{ template "consul.fullname" . }}-sync-catalog verbs: - use {{- end }} +{{- end }} diff --git a/templates/sync-catalog-podsecuritypolicy.yaml b/templates/sync-catalog-podsecuritypolicy.yaml index 47d2d4f1cd..141cbcc6c2 100644 --- a/templates/sync-catalog-podsecuritypolicy.yaml +++ b/templates/sync-catalog-podsecuritypolicy.yaml @@ -1,4 +1,4 @@ -{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: diff --git a/values.yaml b/values.yaml index 5bb29e1e5b..a2cb5dbfc0 100644 --- a/values.yaml +++ b/values.yaml @@ -32,6 +32,11 @@ global: # currently: https://github.com/hashicorp/consul/issues/1858 datacenter: dc1 + # enablePodSecurityPolicies is a boolean flag that controls whether pod + # security policies are created for the consul components created by this + # chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + enablePodSecurityPolicies: false + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From 7b66bd46b8fc584ebdb6f1e2ca8af317d528400d Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 6 Dec 2018 16:15:56 -0800 Subject: [PATCH 162/739] Add tests for pod security policies This additionally adds tests for the new cluster roles and role bindings added for the servers and clients. It standardizes the naming of all files and the format of the test files. --- templates/client-clusterrole.yaml | 14 ++--- templates/server-clusterrole.yaml | 2 +- ...ole.yaml => sync-catalog-clusterrole.yaml} | 7 +-- ...l => sync-catalog-clusterrolebinding.yaml} | 0 ....yaml => sync-catalog-serviceaccount.yaml} | 0 test/unit/client-clusterrole.bats | 53 +++++++++++++++++++ test/unit/client-clusterrolebinding.bats | 53 +++++++++++++++++++ test/unit/client-podsecuritypolicy.bats | 33 ++++++++++++ test/unit/client-serviceaccount.bats | 53 +++++++++++++++++++ test/unit/connect-inject-clusterrole.bats | 1 + .../connect-inject-clusterrolebinding.bats | 1 + .../connect-inject-podsecuritypolicy.bats | 44 +++++++++++++++ test/unit/connect-inject-serviceaccount.bats | 1 + test/unit/server-clusterrole.bats | 53 +++++++++++++++++++ test/unit/server-clusterrolebinding.bats | 53 +++++++++++++++++++ test/unit/server-podsecuritypolicy.bats | 33 ++++++++++++ test/unit/server-serviceaccount.bats | 53 +++++++++++++++++++ ...ole.bats => sync-catalog-clusterrole.bats} | 20 +++---- ...s => sync-catalog-clusterrolebinding.bats} | 20 +++---- test/unit/sync-catalog-podsecuritypolicy.bats | 44 +++++++++++++++ ....bats => sync-catalog-serviceaccount.bats} | 20 +++---- 21 files changed, 515 insertions(+), 43 deletions(-) rename templates/{sync-catalog-cluster-role.yaml => sync-catalog-clusterrole.yaml} (93%) rename templates/{sync-catalog-cluster-role-binding.yaml => sync-catalog-clusterrolebinding.yaml} (100%) rename templates/{sync-catalog-service-account.yaml => sync-catalog-serviceaccount.yaml} (100%) create mode 100644 test/unit/client-clusterrole.bats create mode 100644 test/unit/client-clusterrolebinding.bats create mode 100644 test/unit/client-podsecuritypolicy.bats create mode 100644 test/unit/client-serviceaccount.bats create mode 100644 test/unit/connect-inject-podsecuritypolicy.bats create mode 100644 test/unit/server-clusterrole.bats create mode 100644 test/unit/server-clusterrolebinding.bats create mode 100644 test/unit/server-podsecuritypolicy.bats create mode 100644 test/unit/server-serviceaccount.bats rename test/unit/{sync-catalog-cluster-role.bats => sync-catalog-clusterrole.bats} (62%) rename test/unit/{sync-catalog-cluster-role-binding.bats => sync-catalog-clusterrolebinding.bats} (59%) create mode 100644 test/unit/sync-catalog-podsecuritypolicy.bats rename test/unit/{sync-service-account.bats => sync-catalog-serviceaccount.bats} (61%) diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index e4f210e592..0e84b59e7e 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -8,13 +8,13 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -rules: {{- if .Values.global.enablePodSecurityPolicies }} -- apiGroups: ["policy"] - resources: ["podsecuritypolicies"] - resourceNames: - - {{ template "consul.fullname" . }}-client - verbs: - - use +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-client + verbs: + - use {{- end }} {{- end }} diff --git a/templates/server-clusterrole.yaml b/templates/server-clusterrole.yaml index ae8a2d7903..93e2557384 100644 --- a/templates/server-clusterrole.yaml +++ b/templates/server-clusterrole.yaml @@ -8,8 +8,8 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -rules: {{- if .Values.global.enablePodSecurityPolicies }} +rules: - apiGroups: ["policy"] resources: ["podsecuritypolicies"] resourceNames: diff --git a/templates/sync-catalog-cluster-role.yaml b/templates/sync-catalog-clusterrole.yaml similarity index 93% rename from templates/sync-catalog-cluster-role.yaml rename to templates/sync-catalog-clusterrole.yaml index 676ef44d19..b30dad4e60 100644 --- a/templates/sync-catalog-cluster-role.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -27,15 +27,12 @@ rules: - nodes verbs: - get - - apiGroups: ["policy"] - resources: - - podsecuritypolicies {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourceNames: - - {{ template "consul.fullname" . }}-sync-catalog verbs: - use + resourceNames: + - {{ template "consul.fullname" . }}-sync-catalog {{- end }} {{- end }} diff --git a/templates/sync-catalog-cluster-role-binding.yaml b/templates/sync-catalog-clusterrolebinding.yaml similarity index 100% rename from templates/sync-catalog-cluster-role-binding.yaml rename to templates/sync-catalog-clusterrolebinding.yaml diff --git a/templates/sync-catalog-service-account.yaml b/templates/sync-catalog-serviceaccount.yaml similarity index 100% rename from templates/sync-catalog-service-account.yaml rename to templates/sync-catalog-serviceaccount.yaml diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats new file mode 100644 index 0000000000..13ded5fec8 --- /dev/null +++ b/test/unit/client-clusterrole.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/ClusterRole: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ClusterRole: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ClusterRole: can be enabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ClusterRole: disabled with client.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ClusterRole: enabled with client.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/client-clusterrolebinding.bats b/test/unit/client-clusterrolebinding.bats new file mode 100644 index 0000000000..31bd33f77a --- /dev/null +++ b/test/unit/client-clusterrolebinding.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/ClusterRoleBinding: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ClusterRoleBinding: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ClusterRoleBinding: disabled with client disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrolebinding.yaml \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ClusterRoleBinding: enabled with client enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrolebinding.yaml \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ClusterRoleBinding: enabled with client enabled and global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/test/unit/client-podsecuritypolicy.bats b/test/unit/client-podsecuritypolicy.bats new file mode 100644 index 0000000000..9cea7ea380 --- /dev/null +++ b/test/unit/client-podsecuritypolicy.bats @@ -0,0 +1,33 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/PodSecurityPolicy: disabled with client disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'client.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/PodSecurityPolicy: enabled with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/client-serviceaccount.bats b/test/unit/client-serviceaccount.bats new file mode 100644 index 0000000000..f787e376ea --- /dev/null +++ b/test/unit/client-serviceaccount.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/ServiceAccount: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ServiceAccount: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-serviceaccount.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ServiceAccount: disabled with client disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-serviceaccount.yaml \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ServiceAccount: enabled with client enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-serviceaccount.yaml \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ServiceAccount: enabled with client enabled and global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-serviceaccount.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats index cb282edd92..2852f53c82 100644 --- a/test/unit/connect-inject-clusterrole.bats +++ b/test/unit/connect-inject-clusterrole.bats @@ -1,6 +1,7 @@ #!/usr/bin/env bats load _helpers + @test "connectInject/ClusterRole: disabled by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/connect-inject-clusterrolebinding.bats b/test/unit/connect-inject-clusterrolebinding.bats index a9a57108cd..3e21eec14b 100644 --- a/test/unit/connect-inject-clusterrolebinding.bats +++ b/test/unit/connect-inject-clusterrolebinding.bats @@ -1,6 +1,7 @@ #!/usr/bin/env bats load _helpers + @test "connectInject/ClusterRoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/connect-inject-podsecuritypolicy.bats b/test/unit/connect-inject-podsecuritypolicy.bats new file mode 100644 index 0000000000..ee14dc376f --- /dev/null +++ b/test/unit/connect-inject-podsecuritypolicy.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInject/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/PodSecurityPolicy: disabled by default with connectInject enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-podsecuritypolicy.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/PodSecurityPolicy: disabled with connectInject disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-podsecuritypolicy.yaml \ + --set 'connectInject.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/PodSecurityPolicy: enabled with connectInject enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-podsecuritypolicy.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-serviceaccount.bats b/test/unit/connect-inject-serviceaccount.bats index 1fc77be8ab..e5b3a5a790 100644 --- a/test/unit/connect-inject-serviceaccount.bats +++ b/test/unit/connect-inject-serviceaccount.bats @@ -1,6 +1,7 @@ #!/usr/bin/env bats load _helpers + @test "connectInject/ServiceAccount: disabled by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-clusterrole.bats b/test/unit/server-clusterrole.bats new file mode 100644 index 0000000000..de8d1a9974 --- /dev/null +++ b/test/unit/server-clusterrole.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/ClusterRole: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ClusterRole: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ClusterRole: can be enabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ClusterRole: disabled with server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ClusterRole: enabled with server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-clusterrolebinding.bats b/test/unit/server-clusterrolebinding.bats new file mode 100644 index 0000000000..125b767ed4 --- /dev/null +++ b/test/unit/server-clusterrolebinding.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/ClusterRoleBinding: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ClusterRoleBinding: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ClusterRoleBinding: disabled with server disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrolebinding.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ClusterRoleBinding: enabled with server enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrolebinding.yaml \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ClusterRoleBinding: enabled with server enabled and global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/test/unit/server-podsecuritypolicy.bats b/test/unit/server-podsecuritypolicy.bats new file mode 100644 index 0000000000..91e010d1b7 --- /dev/null +++ b/test/unit/server-podsecuritypolicy.bats @@ -0,0 +1,33 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/PodSecurityPolicy: disabled with server disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-podsecuritypolicy.yaml \ + --set 'server.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/PodSecurityPolicy: enabled with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-serviceaccount.bats b/test/unit/server-serviceaccount.bats new file mode 100644 index 0000000000..bf1a742803 --- /dev/null +++ b/test/unit/server-serviceaccount.bats @@ -0,0 +1,53 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/ServiceAccount: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ServiceAccount: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-serviceaccount.yaml \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ServiceAccount: disabled with server disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-serviceaccount.yaml \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ServiceAccount: enabled with server enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-serviceaccount.yaml \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ServiceAccount: enabled with server enabled and global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-serviceaccount.yaml \ + --set 'global.enabled=false' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/sync-catalog-cluster-role.bats b/test/unit/sync-catalog-clusterrole.bats similarity index 62% rename from test/unit/sync-catalog-cluster-role.bats rename to test/unit/sync-catalog-clusterrole.bats index 557c9e50a5..b816971d9f 100755 --- a/test/unit/sync-catalog-cluster-role.bats +++ b/test/unit/sync-catalog-clusterrole.bats @@ -2,49 +2,49 @@ load _helpers -@test "sync/ClusterRole: disabled by default" { +@test "syncCatalog/ClusterRole: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role.yaml \ + -x templates/sync-catalog-clusterrole.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRole: disabled with global.enabled=false" { +@test "syncCatalog/ClusterRole: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role.yaml \ + -x templates/sync-catalog-clusterrole.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRole: disabled with sync disabled" { +@test "syncCatalog/ClusterRole: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role.yaml \ + -x templates/sync-catalog-clusterrole.yaml \ --set 'syncCatalog.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRole: enabled with sync enabled" { +@test "syncCatalog/ClusterRole: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role.yaml \ + -x templates/sync-catalog-clusterrole.yaml \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "sync/ClusterRole: enabled with sync enabled and global.enabled=false" { +@test "syncCatalog/ClusterRole: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role.yaml \ + -x templates/sync-catalog-clusterrole.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | diff --git a/test/unit/sync-catalog-cluster-role-binding.bats b/test/unit/sync-catalog-clusterrolebinding.bats similarity index 59% rename from test/unit/sync-catalog-cluster-role-binding.bats rename to test/unit/sync-catalog-clusterrolebinding.bats index 3b0434f146..36935d3054 100755 --- a/test/unit/sync-catalog-cluster-role-binding.bats +++ b/test/unit/sync-catalog-clusterrolebinding.bats @@ -2,49 +2,49 @@ load _helpers -@test "sync/ClusterRoleBinding: disabled by default" { +@test "syncCatalog/ClusterRoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role-binding.yaml \ + -x templates/sync-catalog-clusterrolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: disabled with global.enabled=false" { +@test "syncCatalog/ClusterRoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role-binding.yaml \ + -x templates/sync-catalog-clusterrolebinding.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: disabled with sync disabled" { +@test "syncCatalog/ClusterRoleBinding: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role-binding.yaml \ + -x templates/sync-catalog-clusterrolebinding.yaml \ --set 'syncCatalog.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ClusterRoleBinding: enabled with sync enabled" { +@test "syncCatalog/ClusterRoleBinding: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role-binding.yaml \ + -x templates/sync-catalog-clusterrolebinding.yaml \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "sync/ClusterRoleBinding: enabled with sync enabled and global.enabled=false" { +@test "syncCatalog/ClusterRoleBinding: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-cluster-role-binding.yaml \ + -x templates/sync-catalog-clusterrolebinding.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | diff --git a/test/unit/sync-catalog-podsecuritypolicy.bats b/test/unit/sync-catalog-podsecuritypolicy.bats new file mode 100644 index 0000000000..0a0adda093 --- /dev/null +++ b/test/unit/sync-catalog-podsecuritypolicy.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "syncCatalog/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/PodSecurityPolicy: disabled by default with syncCatalog enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-podsecuritypolicy.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/PodSecurityPolicy: disabled with syncCatalog disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-podsecuritypolicy.yaml \ + --set 'syncCatalog.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/PodSecurityPolicy: enabled with syncCatalog enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-podsecuritypolicy.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/sync-service-account.bats b/test/unit/sync-catalog-serviceaccount.bats similarity index 61% rename from test/unit/sync-service-account.bats rename to test/unit/sync-catalog-serviceaccount.bats index 27238e2840..f4af2306a9 100755 --- a/test/unit/sync-service-account.bats +++ b/test/unit/sync-catalog-serviceaccount.bats @@ -2,49 +2,49 @@ load _helpers -@test "sync/ServiceAccount: disabled by default" { +@test "syncCatalog/ServiceAccount: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-service-account.yaml \ + -x templates/sync-catalog-serviceaccount.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: disabled with global.enabled=false" { +@test "syncCatalog/ServiceAccount: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-service-account.yaml \ + -x templates/sync-catalog-serviceaccount.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: disabled with sync disabled" { +@test "syncCatalog/ServiceAccount: disabled with sync disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-service-account.yaml \ + -x templates/sync-catalog-serviceaccount.yaml \ --set 'syncCatalog.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "sync/ServiceAccount: enabled with sync enabled" { +@test "syncCatalog/ServiceAccount: enabled with sync enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-service-account.yaml \ + -x templates/sync-catalog-serviceaccount.yaml \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "sync/ServiceAccount: enabled with sync enabled and global.enabled=false" { +@test "syncCatalog/ServiceAccount: enabled with sync enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/sync-catalog-service-account.yaml \ + -x templates/sync-catalog-serviceaccount.yaml \ --set 'global.enabled=false' \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | From 8456bbe88326cad8a0513953e0f4651ec728a35b Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 5 Mar 2019 14:20:11 -0800 Subject: [PATCH 163/739] Remove AppArmor-specific comments --- templates/client-podsecuritypolicy.yaml | 1 - templates/connect-inject-podsecuritypolicy.yaml | 1 - templates/server-podsecuritypolicy.yaml | 1 - templates/sync-catalog-podsecuritypolicy.yaml | 1 - 4 files changed, 4 deletions(-) diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index da9d0b1632..87a44227a4 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -33,7 +33,6 @@ spec: # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' diff --git a/templates/connect-inject-podsecuritypolicy.yaml b/templates/connect-inject-podsecuritypolicy.yaml index b1fee54cc8..571c609d68 100644 --- a/templates/connect-inject-podsecuritypolicy.yaml +++ b/templates/connect-inject-podsecuritypolicy.yaml @@ -30,7 +30,6 @@ spec: # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' diff --git a/templates/server-podsecuritypolicy.yaml b/templates/server-podsecuritypolicy.yaml index ef8ecfdb93..4687fda999 100644 --- a/templates/server-podsecuritypolicy.yaml +++ b/templates/server-podsecuritypolicy.yaml @@ -31,7 +31,6 @@ spec: # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' diff --git a/templates/sync-catalog-podsecuritypolicy.yaml b/templates/sync-catalog-podsecuritypolicy.yaml index 141cbcc6c2..93190d80a4 100644 --- a/templates/sync-catalog-podsecuritypolicy.yaml +++ b/templates/sync-catalog-podsecuritypolicy.yaml @@ -30,7 +30,6 @@ spec: # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' From 6c3af2a64c46a9ef189806e7d233a000587af6b6 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 13 Mar 2019 18:00:46 -0700 Subject: [PATCH 164/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a8caab69..e3195a73f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ IMPROVEMENTS: * Add annotation and additional spec values for the UI service * Add liveness and readiness checks to the catalog sync pod [[consul-k8s GH 57](https://github.com/hashicorp/consul-k8s/issues/57)] * Support custom annotations for Consul clients and servers + * Support PodSecurityPolicies for Consul components + * Add service accounts and cluster roles/role bindings for each Consul component BUG FIXES: From 37156696e59dc57110355bf750475e45e8a04edb Mon Sep 17 00:00:00 2001 From: Kfir Breger Date: Thu, 7 Feb 2019 10:00:16 +0100 Subject: [PATCH 165/739] Making the metadata volume claim metadata name configurable --- templates/server-statefulset.yaml | 4 ++-- values.yaml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index a3b03c1adf..599b60300e 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -108,7 +108,7 @@ spec: {{- end }} -server volumeMounts: - - name: data + - name: {{ .Values.server.storageClaimName }} mountPath: /consul/data - name: config mountPath: /consul/config @@ -160,7 +160,7 @@ spec: {{- end }} volumeClaimTemplates: - metadata: - name: data + name: {{ .Values.server.storageClaimName }} spec: accessModes: - ReadWriteOnce diff --git a/values.yaml b/values.yaml index a2cb5dbfc0..4f16644740 100644 --- a/values.yaml +++ b/values.yaml @@ -62,6 +62,7 @@ server: # to null (the Kube cluster will pick the default). storage: 10Gi storageClass: null + storageClaimName: "data" # connect will enable Connect on all the servers, initializing a CA # for Connect-related connections. Other customizations can be done From 7d2b84e413af3d661ccf713641e6358dc3ad276e Mon Sep 17 00:00:00 2001 From: Sarah Christoff Date: Thu, 14 Mar 2019 15:28:57 -0500 Subject: [PATCH 166/739] Update metadama volume name to include namespace This creates data volumes with unqiue names based off the namespace in which it is deployed. --- templates/server-statefulset.yaml | 4 ++-- values.yaml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 599b60300e..c16c2a6124 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -108,7 +108,7 @@ spec: {{- end }} -server volumeMounts: - - name: {{ .Values.server.storageClaimName }} + - name: data-{{ .Release.Namespace }} mountPath: /consul/data - name: config mountPath: /consul/config @@ -160,7 +160,7 @@ spec: {{- end }} volumeClaimTemplates: - metadata: - name: {{ .Values.server.storageClaimName }} + name: data-{{ .Release.Namespace }} spec: accessModes: - ReadWriteOnce diff --git a/values.yaml b/values.yaml index 4f16644740..a2cb5dbfc0 100644 --- a/values.yaml +++ b/values.yaml @@ -62,7 +62,6 @@ server: # to null (the Kube cluster will pick the default). storage: 10Gi storageClass: null - storageClaimName: "data" # connect will enable Connect on all the servers, initializing a CA # for Connect-related connections. Other customizations can be done From ab33144fcdb96224ddf9c04f0a94ce848f4b0e20 Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Fri, 15 Mar 2019 13:27:10 -0400 Subject: [PATCH 167/739] Support gossip encryption --- templates/client-daemonset.yaml | 3 +++ templates/server-statefulset.yaml | 3 +++ values.yaml | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index f15ec38cf3..64635d7a8d 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -96,6 +96,9 @@ spec: {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ + {{- if .Values.global.gossipKey }} + -encrypt="{{ .Values.global.gossipKey }}" \ + {{- end }} {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} {{- range $value := .Values.client.join }} -retry-join="{{ $value }}" \ diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index c16c2a6124..4ade90dee5 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -97,6 +97,9 @@ spec: -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ -domain={{ .Values.global.domain }} \ + {{- if .Values.global.gossipKey }} + -encrypt="{{ .Values.global.gossipKey }}" \ + {{- end }} {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ {{- end }} diff --git a/values.yaml b/values.yaml index a2cb5dbfc0..a001c53142 100644 --- a/values.yaml +++ b/values.yaml @@ -37,6 +37,11 @@ global: # chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/ enablePodSecurityPolicies: false + # Gossip encryption key. To disable gossip encryption, set this to null. + # Note: DO NOT use the provided key in production. Generate your own with + # "consul keygen" and paste it here. + gossipKey: cg8StVXbQJ0gPvMd9o7yrg== + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From f6a27d8ccbb8bacb6f75b64f0027d2d20cf8c1ec Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Fri, 15 Mar 2019 23:16:00 -0400 Subject: [PATCH 168/739] Moved gossip key into a secret and added unit tests --- templates/client-daemonset.yaml | 11 +++- templates/server-statefulset.yaml | 11 +++- test/unit/gossip-client-daemonset.bats | 71 ++++++++++++++++++++++++ test/unit/gossip-server-statefulset.bats | 71 ++++++++++++++++++++++++ values.yaml | 12 ++-- 5 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 test/unit/gossip-client-daemonset.bats create mode 100644 test/unit/gossip-server-statefulset.bats diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 64635d7a8d..a513504c7c 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -74,6 +74,13 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + - name: GOSSIP_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.global.gossipEncryption.secretName }} + key: {{ .Values.global.gossipEncryption.secretKey }} + {{- end }} command: - "/bin/sh" - "-ec" @@ -96,8 +103,8 @@ spec: {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ - {{- if .Values.global.gossipKey }} - -encrypt="{{ .Values.global.gossipKey }}" \ + {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + -encrypt="${GOSSIP_KEY}" \ {{- end }} {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} {{- range $value := .Values.client.join }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 4ade90dee5..059bd3efca 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -77,6 +77,13 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + - name: GOSSIP_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.global.gossipEncryption.secretName }} + key: {{ .Values.global.gossipEncryption.secretKey }} + {{- end }} command: - "/bin/sh" - "-ec" @@ -97,8 +104,8 @@ spec: -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ -domain={{ .Values.global.domain }} \ - {{- if .Values.global.gossipKey }} - -encrypt="{{ .Values.global.gossipKey }}" \ + {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + -encrypt="${GOSSIP_KEY}" \ {{- end }} {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ diff --git a/test/unit/gossip-client-daemonset.bats b/test/unit/gossip-client-daemonset.bats new file mode 100644 index 0000000000..2fd9f6d70f --- /dev/null +++ b/test/unit/gossip-client-daemonset.bats @@ -0,0 +1,71 @@ +#!/usr/bin/env bats + +load _helpers + +@test "global/gossipEncryption: disabled in client DaemonSet by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: disabled in client DaemonSet when servers are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enabled=false' \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "global/gossipEncryption: disabled in client DaemonSet when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: disabled in client DaemonSet when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: environment variable present in client DaemonSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "global/gossipEncryption: CLI option present in client DaemonSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/gossip-server-statefulset.bats b/test/unit/gossip-server-statefulset.bats new file mode 100644 index 0000000000..065c197405 --- /dev/null +++ b/test/unit/gossip-server-statefulset.bats @@ -0,0 +1,71 @@ +#!/usr/bin/env bats + +load _helpers + +@test "global/gossipEncryption: disabled in server StatefulSet by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: disabled in server StatefulSet when servers are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enabled=false' \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "global/gossipEncryption: disabled in server StatefulSet when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: disabled in server StatefulSet when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "global/gossipEncryption: environment variable present in server StatefulSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "global/gossipEncryption: CLI option present in server StatefulSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index a001c53142..7223ca19d8 100644 --- a/values.yaml +++ b/values.yaml @@ -37,10 +37,14 @@ global: # chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/ enablePodSecurityPolicies: false - # Gossip encryption key. To disable gossip encryption, set this to null. - # Note: DO NOT use the provided key in production. Generate your own with - # "consul keygen" and paste it here. - gossipKey: cg8StVXbQJ0gPvMd9o7yrg== + # Gossip encryption key. To enable gossip encryption, provide the name of + # a Kubernetes secret that contains a gossip key. You can create a gossip + # key with the "consul keygen" command. + # See https://www.consul.io/docs/commands/keygen.html + gossipEncryption: + enabled: false + secretName: null + secretKey: null # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to From 9be52b9da66b0777e52a29e3e9583230e54a1f39 Mon Sep 17 00:00:00 2001 From: Yong Wen Chua Date: Sat, 16 Mar 2019 09:28:35 +0800 Subject: [PATCH 169/739] Support tolerations on clients and servers --- templates/client-daemonset.yaml | 4 ++++ templates/server-statefulset.yaml | 4 ++++ test/unit/client-daemonset.bats | 22 ++++++++++++++++++++++ test/unit/server-statefulset.bats | 22 ++++++++++++++++++++++ values.yaml | 14 ++++++++++++++ 5 files changed, 66 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index f15ec38cf3..d47c04e9d6 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -32,6 +32,10 @@ spec: {{- tpl .Values.client.annotations . | nindent 8 }} {{- end }} spec: + {{- if .Values.client.tolerations }} + tolerations: + {{ tpl .Values.client.tolerations . | nindent 8 | trim }} + {{- end }} terminationGracePeriodSeconds: 10 serviceAccountName: {{ template "consul.fullname" . }}-client diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index c16c2a6124..daacb2e9fd 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -44,6 +44,10 @@ spec: {{- if .Values.server.affinity }} affinity: {{ tpl .Values.server.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: + {{ tpl .Values.server.tolerations . | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: 10 serviceAccountName: {{ template "consul.fullname" . }}-server diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 90eaa59e49..a6d6855bc2 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -264,3 +264,25 @@ load _helpers yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# tolerations + +@test "client/DaemonSet: tolerations not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec | .tolerations? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: tolerations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.tolerations=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 2e842a62e1..9349488f83 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -310,3 +310,25 @@ load _helpers yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# tolerations + +@test "server/StatefulSet: tolerations not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec | .tolerations? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: tolerations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.tolerations=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index a2cb5dbfc0..f05331fc50 100644 --- a/values.yaml +++ b/values.yaml @@ -114,6 +114,11 @@ server: component: server topologyKey: kubernetes.io/hostname + # Toleration Settings for server pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: "" + # used to assign priority to server pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" @@ -154,6 +159,15 @@ client: # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul + # Toleration Settings for Client pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + # The example below will allow Client pods to run on every node + # regardless of taints + # tolerations: | + # - operator: "Exists" + tolerations: "" + # used to assign priority to client pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" From 25c9827527e7b7440d1e593151757c5215945390 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 18 Mar 2019 11:19:42 -0700 Subject: [PATCH 170/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3195a73f0..a2c0bfea16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ IMPROVEMENTS: * Support custom annotations for Consul clients and servers * Support PodSecurityPolicies for Consul components * Add service accounts and cluster roles/role bindings for each Consul component + * Support tolerations on Consul client and server pods BUG FIXES: From bf1e21b2a1c449d3fb3349f164345d36d4136307 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 18 Mar 2019 18:15:47 -0400 Subject: [PATCH 171/739] Update test/unit/gossip-client-daemonset.bats Co-Authored-By: tradel --- test/unit/gossip-client-daemonset.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/gossip-client-daemonset.bats b/test/unit/gossip-client-daemonset.bats index 2fd9f6d70f..8b2d221260 100644 --- a/test/unit/gossip-client-daemonset.bats +++ b/test/unit/gossip-client-daemonset.bats @@ -14,7 +14,7 @@ load _helpers @test "global/gossipEncryption: disabled in client DaemonSet when servers are disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/client-daemonset.yaml \ --set 'server.enabled=false' \ --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretName=foo' \ From b7cee497b5da261ebc8899983b4da88ad327fc6d Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Mon, 18 Mar 2019 18:22:38 -0400 Subject: [PATCH 172/739] Moved Gossip tests into existing client/server test suites --- test/unit/client-daemonset.bats | 71 ++++++++++++++++++++++++ test/unit/gossip-client-daemonset.bats | 71 ------------------------ test/unit/gossip-server-statefulset.bats | 71 ------------------------ test/unit/server-statefulset.bats | 71 ++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 142 deletions(-) delete mode 100644 test/unit/gossip-client-daemonset.bats delete mode 100644 test/unit/gossip-server-statefulset.bats diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 90eaa59e49..77e54c468c 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -264,3 +264,74 @@ load _helpers yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# gossip encryption + +@test "client/DaemonSet: gossip encryption disabled in client DaemonSet by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "client/DaemonSet: gossip encryption disabled in client DaemonSet when clients are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.enabled=false' \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/DaemonSet: gossip encryption disabled in client DaemonSet when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "client/DaemonSet: gossip encryption disabled in client DaemonSet when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "client/DaemonSet: gossip environment variable present in client DaemonSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: gossip CLI option present in client DaemonSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/gossip-client-daemonset.bats b/test/unit/gossip-client-daemonset.bats deleted file mode 100644 index 8b2d221260..0000000000 --- a/test/unit/gossip-client-daemonset.bats +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bats - -load _helpers - -@test "global/gossipEncryption: disabled in client DaemonSet by default" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: disabled in client DaemonSet when servers are disabled" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretName=foo' \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - -@test "global/gossipEncryption: disabled in client DaemonSet when secretName is missing" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: disabled in client DaemonSet when secretKey is missing" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretName=foo' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: environment variable present in client DaemonSet when all config is provided" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=foo' \ - --set 'global.gossipEncryption.secretName=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "global/gossipEncryption: CLI option present in client DaemonSet when all config is provided" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=foo' \ - --set 'global.gossipEncryption.secretName=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} diff --git a/test/unit/gossip-server-statefulset.bats b/test/unit/gossip-server-statefulset.bats deleted file mode 100644 index 065c197405..0000000000 --- a/test/unit/gossip-server-statefulset.bats +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bats - -load _helpers - -@test "global/gossipEncryption: disabled in server StatefulSet by default" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: disabled in server StatefulSet when servers are disabled" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license.yaml \ - --set 'server.enabled=false' \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretName=foo' \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - -@test "global/gossipEncryption: disabled in server StatefulSet when secretName is missing" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: disabled in server StatefulSet when secretKey is missing" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretName=foo' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "" ] -} - -@test "global/gossipEncryption: environment variable present in server StatefulSet when all config is provided" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=foo' \ - --set 'global.gossipEncryption.secretName=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "global/gossipEncryption: CLI option present in server StatefulSet when all config is provided" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ - --set 'global.gossipEncryption.secretKey=foo' \ - --set 'global.gossipEncryption.secretName=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 2e842a62e1..30197a8748 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -310,3 +310,74 @@ load _helpers yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# gossip encryption + +@test "server/StatefulSet: gossip encryption disabled in server StatefulSet by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when servers are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enabled=false' \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +@test "server/StatefulSet: gossip environment variable present in server StatefulSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: gossip CLI option present in server StatefulSet when all config is provided" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=true' \ + --set 'global.gossipEncryption.secretKey=foo' \ + --set 'global.gossipEncryption.secretName=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From 87c49d849b8231ff5d628f518b2b20a44d19246e Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Mon, 18 Mar 2019 18:26:01 -0400 Subject: [PATCH 173/739] Test for absence of -encrypt option --- test/unit/client-daemonset.bats | 11 ++++++++++- test/unit/server-statefulset.bats | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 77e54c468c..c94ba885e8 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -324,7 +324,16 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: gossip CLI option present in client DaemonSet when all config is provided" { +@test "client/DaemonSet: encrypt CLI option not present in client DaemonSet when encryption disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.gossipEncryption.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} +@test "client/DaemonSet: encrypt CLI option present in client DaemonSet when all config is provided" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 30197a8748..efac10643f 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -370,7 +370,17 @@ load _helpers [ "${actual}" = "true" ] } -@test "server/StatefulSet: gossip CLI option present in server StatefulSet when all config is provided" { +@test "server/StatefulSet: encrypt CLI option not present in server StatefulSet when encryption disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.gossipEncryption.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/StatefulSet: encrypt CLI option present in server StatefulSet when all config is provided" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ From 7a29155875d7b9cf4a80e04144b6108ea08f140a Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Tue, 19 Mar 2019 15:41:38 -0400 Subject: [PATCH 174/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c0bfea16..abaf38e0b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ IMPROVEMENTS: * Support PodSecurityPolicies for Consul components * Add service accounts and cluster roles/role bindings for each Consul component * Support tolerations on Consul client and server pods + * Support gossip protocol encryption BUG FIXES: From a1327c16709e46b4da33433baab633bd55d22399 Mon Sep 17 00:00:00 2001 From: Paulo Machado Date: Tue, 26 Feb 2019 17:24:23 -0800 Subject: [PATCH 175/739] Add support for custom environment variables - Adds _helpers method to encapsulate template logic - Only server stateful and client deployment specs supported --- templates/_helpers.tpl | 12 ++++++++++++ templates/client-daemonset.yaml | 1 + templates/server-statefulset.yaml | 1 + test/unit/client-daemonset.bats | 28 ++++++++++++++++++++++++++++ test/unit/server-statefulset.bats | 29 ++++++++++++++++++++++++++++- values.yaml | 18 ++++++++++++++++++ 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 06292c964c..3b5484d50d 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -51,3 +51,15 @@ Add a special case for replicas=1, where it should default to 0 as well. {{- end -}} {{- end -}} {{- end -}} + +{{/* +Inject extra environment vars in the format key:value, if populated +*/}} +{{- define "consul.extraEnvironmentVars" -}} +{{- if .extraEnvironmentVars -}} +{{- range $key, $value := .extraEnvironmentVars }} +- name: {{ $key }} + value: {{ $value | quote }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index d6d1ce4bff..230af73581 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -85,6 +85,7 @@ spec: name: {{ .Values.global.gossipEncryption.secretName }} key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.client | nindent 12 }} command: - "/bin/sh" - "-ec" diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 7341f7e74f..93b4e7ce6a 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -88,6 +88,7 @@ spec: name: {{ .Values.global.gossipEncryption.secretName }} key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }} command: - "/bin/sh" - "-ec" diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 643f51d8ab..5bf7b88c8d 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -365,4 +365,32 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) [ "${actual}" = "true" ] + +#-------------------------------------------------------------------- +# extraEnvironmentVariables + +@test "client/DaemonSet: custom environment variables" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.extraEnvironmentVars.custom_proxy=fakeproxy' \ + --set 'client.extraEnvironmentVars.no_proxy=custom_no_proxy' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.[3].name' | tee /dev/stderr) + [ "${actual}" = "custom_proxy" ] + + local actual=$(echo $object | + yq -r '.[3].value' | tee /dev/stderr) + [ "${actual}" = "fakeproxy" ] + + local actual=$(echo $object | + yq -r '.[4].name' | tee /dev/stderr) + [ "${actual}" = "no_proxy" ] + + local actual=$(echo $object | + yq -r '.[4].value' | tee /dev/stderr) + [ "${actual}" = "custom_no_proxy" ] } diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 03a9cbc2b4..10d711af45 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -266,7 +266,6 @@ load _helpers [ "${actual}" = "true" ] } - #-------------------------------------------------------------------- # priorityClassName @@ -414,3 +413,31 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# extraEnvironmentVariables + +@test "server/StatefulSet: custom environment variables" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraEnvironmentVars.custom_proxy=fakeproxy' \ + --set 'server.extraEnvironmentVars.no_proxy=custom_no_proxy' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "custom_proxy" ] + + local actual=$(echo $object | + yq -r '.[2].value' | tee /dev/stderr) + [ "${actual}" = "fakeproxy" ] + + local actual=$(echo $object | + yq -r '.[3].name' | tee /dev/stderr) + [ "${actual}" = "no_proxy" ] + + local actual=$(echo $object | + yq -r '.[3].value' | tee /dev/stderr) + [ "${actual}" = "custom_no_proxy" ] +} diff --git a/values.yaml b/values.yaml index 6c6c34dd9f..235cf249ba 100644 --- a/values.yaml +++ b/values.yaml @@ -137,6 +137,15 @@ server: # the annotations to apply to the server pods annotations: null + # extraEnvVars is a list of extra enviroment variables to set with the stateful set. These could be + # used to include proxy settings required for cloud auto-join feature, + # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure + # custom consul parameters. + extraEnvironmentVars: {} + # http_proxy: http://localhost:3128 + # https_proxy: http://localhost:3128 + # no_proxy: internal.domain.com + # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. @@ -186,6 +195,15 @@ client: # the annotations to apply to the client pods annotations: null + # extraEnvVars is a list of extra enviroment variables to set with the pod. These could be + # used to include proxy settings required for cloud auto-join feature, + # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure + # custom consul parameters. + extraEnvironmentVars: {} + # http_proxy: http://localhost:3128, + # https_proxy: http://localhost:3128, + # no_proxy: internal.domain.com + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From fb2725a8abcd8e7e3995f299d8dccfdee99bfb99 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 20 Mar 2019 22:49:15 -0700 Subject: [PATCH 176/739] Update a couple minor formatting details, rebases on master --- test/unit/client-daemonset.bats | 2 ++ values.yaml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 5bf7b88c8d..bdf0f55e03 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -355,6 +355,7 @@ load _helpers yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) [ "${actual}" = "false" ] } + @test "client/DaemonSet: encrypt CLI option present in client DaemonSet when all config is provided" { cd `chart_dir` local actual=$(helm template \ @@ -365,6 +366,7 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) [ "${actual}" = "true" ] +} #-------------------------------------------------------------------- # extraEnvironmentVariables diff --git a/values.yaml b/values.yaml index 235cf249ba..00513c8bdf 100644 --- a/values.yaml +++ b/values.yaml @@ -142,8 +142,8 @@ server: # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure # custom consul parameters. extraEnvironmentVars: {} - # http_proxy: http://localhost:3128 - # https_proxy: http://localhost:3128 + # http_proxy: http://localhost:3128, + # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com # Client, when enabled, configures Consul clients to run on every node From b12f92ea1249e4c01398284e079e99f8bec9dd18 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 20 Mar 2019 22:52:50 -0700 Subject: [PATCH 177/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index abaf38e0b8..793fc9c4c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ IMPROVEMENTS: * Add service accounts and cluster roles/role bindings for each Consul component * Support tolerations on Consul client and server pods * Support gossip protocol encryption + * Allows custom environment variables for Consul client and server pods BUG FIXES: From ac78eef222674d786746e0a1cd06b889e019036d Mon Sep 17 00:00:00 2001 From: Joakim Bakke Hellum Date: Thu, 11 Oct 2018 13:11:06 +0200 Subject: [PATCH 178/739] add support for tolerations label --- templates/client-daemonset.yaml | 4 ++++ templates/connect-inject-deployment.yaml | 4 ++++ templates/server-statefulset.yaml | 4 ++++ templates/sync-catalog-deployment.yaml | 4 ++++ values.yaml | 16 ++++++++++++++++ 5 files changed, 32 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 230af73581..427acb541f 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -173,4 +173,8 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} + {{- if .Values.client.tolerations }} + tolerations: +{{ toYaml .Values.client.tolerations | indent 8 }} + {{- end }} {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 3564e128a9..583a23d5a3 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -87,4 +87,8 @@ spec: secret: secretName: {{ .Values.connectInject.certs.secretName }} {{- end }} + {{- if .Values.connectInject.tolerations }} + tolerations: +{{ toYaml .Values.connectInject.tolerations | indent 8 }} + {{- end }} {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 93b4e7ce6a..370719f08e 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -173,6 +173,10 @@ spec: resources: {{ tpl .Values.server.resources . | nindent 12 | trim }} {{- end }} + {{- if .Values.server.tolerations }} + tolerations: +{{ toYaml .Values.server.tolerations | indent 8 }} + {{- end }} volumeClaimTemplates: - metadata: name: data-{{ .Release.Namespace }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index bed6f39d99..ee2f7de48a 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -95,4 +95,8 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 + {{- if .Values.syncCatalog.tolerations }} + tolerations: +{{ toYaml .Values.syncCatalog.tolerations | indent 8 }} + {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index 00513c8bdf..10ec9d326d 100644 --- a/values.yaml +++ b/values.yaml @@ -109,6 +109,10 @@ server: # - type: secret (or "configMap") # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul + + ## server tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] # Affinity Settings # Commenting out or setting as empty the affinity variable, will allow @@ -204,6 +208,10 @@ client: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com + ## client tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns @@ -285,6 +293,10 @@ syncCatalog: secretName: null secretKey: null + ## syncCatalog tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false @@ -325,3 +337,7 @@ connectInject: # defaults but can be customized if necessary. certName: tls.crt keyName: tls.key + + ## connectInject tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] \ No newline at end of file From 194348e592fcebaf99ff55b2b06a1f6badc72973 Mon Sep 17 00:00:00 2001 From: Joakim Bakke Hellum Date: Thu, 11 Oct 2018 13:20:45 +0200 Subject: [PATCH 179/739] add nodeSelector support --- templates/client-daemonset.yaml | 4 ++++ templates/connect-inject-deployment.yaml | 4 ++++ templates/server-statefulset.yaml | 4 ++++ templates/sync-catalog-deployment.yaml | 4 ++++ values.yaml | 15 ++++++++++++--- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 427acb541f..38e13f089e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -173,6 +173,10 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} + {{- if .Values.client.nodeSelector }} + nodeSelector: +{{ toYaml .Values.client.nodeSelector | indent 8 }} + {{- end }} {{- if .Values.client.tolerations }} tolerations: {{ toYaml .Values.client.tolerations | indent 8 }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 583a23d5a3..9e0b82fa3a 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -87,6 +87,10 @@ spec: secret: secretName: {{ .Values.connectInject.certs.secretName }} {{- end }} + {{- if .Values.connectInject.nodeSelector }} + nodeSelector: +{{ toYaml .Values.connectInject.nodeSelector | indent 8 }} + {{- end }} {{- if .Values.connectInject.tolerations }} tolerations: {{ toYaml .Values.connectInject.tolerations | indent 8 }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 370719f08e..ebacd7db45 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -173,6 +173,10 @@ spec: resources: {{ tpl .Values.server.resources . | nindent 12 | trim }} {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: +{{ toYaml .Values.server.nodeSelector | indent 8 }} + {{- end }} {{- if .Values.server.tolerations }} tolerations: {{ toYaml .Values.server.tolerations | indent 8 }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index ee2f7de48a..7fef94492b 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -95,6 +95,10 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 + {{- if .Values.syncCatalog.nodeSelector }} + nodeSelector: +{{ toYaml .Values.syncCatalog.nodeSelector | indent 8 }} + {{- end }} {{- if .Values.syncCatalog.tolerations }} tolerations: {{ toYaml .Values.syncCatalog.tolerations | indent 8 }} diff --git a/values.yaml b/values.yaml index 10ec9d326d..8e0efa869d 100644 --- a/values.yaml +++ b/values.yaml @@ -110,7 +110,9 @@ server: # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul - ## server tolerations for pod assignment + ## server node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ tolerations: [] @@ -209,6 +211,9 @@ client: # no_proxy: internal.domain.com ## client tolerations for pod assignment + ## client node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ tolerations: [] @@ -293,7 +298,9 @@ syncCatalog: secretName: null secretKey: null - ## syncCatalog tolerations for pod assignment + ## syncCatalog node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ tolerations: [] @@ -338,6 +345,8 @@ connectInject: certName: tls.crt keyName: tls.key - ## connectInject tolerations for pod assignment + ## connectInject node selectors and tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ tolerations: [] \ No newline at end of file From 2a6789c7f78490a2a346517fd351916efbc81510 Mon Sep 17 00:00:00 2001 From: Joakim Bakke Hellum Date: Thu, 11 Oct 2018 13:33:32 +0200 Subject: [PATCH 180/739] update values.yaml --- values.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/values.yaml b/values.yaml index 8e0efa869d..a3c495779d 100644 --- a/values.yaml +++ b/values.yaml @@ -112,9 +112,9 @@ server: ## server node selectors and tolerations for pod assignment ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - nodeSelector: {} + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - tolerations: [] + # tolerations: [] # Affinity Settings # Commenting out or setting as empty the affinity variable, will allow @@ -213,9 +213,9 @@ client: ## client tolerations for pod assignment ## client node selectors and tolerations for pod assignment ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - nodeSelector: {} + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - tolerations: [] + # tolerations: [] # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) @@ -300,9 +300,9 @@ syncCatalog: ## syncCatalog node selectors and tolerations for pod assignment ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - nodeSelector: {} + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - tolerations: [] + # tolerations: [] # ConnectInject will enable the automatic Connect sidecar injector. connectInject: @@ -347,6 +347,6 @@ connectInject: ## connectInject node selectors and tolerations for pod assignment ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - nodeSelector: {} + # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - tolerations: [] \ No newline at end of file + # tolerations: [] \ No newline at end of file From c0f55437d253b35bdc1af721e4b371a917d5a8f5 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 15 Mar 2019 12:13:13 -0700 Subject: [PATCH 181/739] Separate the nodeSelector implementation from tolerations Additionally, update nodeSelector formatting to match the chart standard since values are generally passed through as multi-line strings. Adds tests for the new options. --- templates/client-daemonset.yaml | 10 ++--- templates/connect-inject-deployment.yaml | 10 ++--- templates/server-statefulset.yaml | 10 ++--- templates/sync-catalog-deployment.yaml | 10 ++--- test/unit/client-daemonset.bats | 22 +++++++++++ test/unit/connect-inject-deployment.bats | 35 ++++++++++++++++- test/unit/server-statefulset.bats | 22 +++++++++++ test/unit/sync-catalog-deployment.bats | 33 ++++++++++++++++ values.yaml | 49 +++++++++++++----------- 9 files changed, 149 insertions(+), 52 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 38e13f089e..0fdca74a7e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -173,12 +173,8 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} - {{- if .Values.client.nodeSelector }} + {{- if .Values.client.nodeSelector }} nodeSelector: -{{ toYaml .Values.client.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.client.tolerations }} - tolerations: -{{ toYaml .Values.client.tolerations | indent 8 }} - {{- end }} + {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} + {{- end }} {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 9e0b82fa3a..8bcfb68125 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -87,12 +87,8 @@ spec: secret: secretName: {{ .Values.connectInject.certs.secretName }} {{- end }} - {{- if .Values.connectInject.nodeSelector }} + {{- if .Values.connectInject.nodeSelector }} nodeSelector: -{{ toYaml .Values.connectInject.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.connectInject.tolerations }} - tolerations: -{{ toYaml .Values.connectInject.tolerations | indent 8 }} - {{- end }} + {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} + {{- end }} {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index ebacd7db45..09d7488c28 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -173,14 +173,10 @@ spec: resources: {{ tpl .Values.server.resources . | nindent 12 | trim }} {{- end }} - {{- if .Values.server.nodeSelector }} + {{- if .Values.server.nodeSelector }} nodeSelector: -{{ toYaml .Values.server.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.server.tolerations }} - tolerations: -{{ toYaml .Values.server.tolerations | indent 8 }} - {{- end }} + {{ tpl .Values.server.nodeSelector . | indent 8 | trim }} + {{- end }} volumeClaimTemplates: - metadata: name: data-{{ .Release.Namespace }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 7fef94492b..8cabb09b04 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -95,12 +95,8 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 - {{- if .Values.syncCatalog.nodeSelector }} + {{- if .Values.syncCatalog.nodeSelector }} nodeSelector: -{{ toYaml .Values.syncCatalog.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.syncCatalog.tolerations }} - tolerations: -{{ toYaml .Values.syncCatalog.tolerations | indent 8 }} - {{- end }} + {{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }} + {{- end }} {{- end }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index bdf0f55e03..6dfdae8a5b 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -221,6 +221,28 @@ load _helpers [ "${actual}" = "1" ] } +#-------------------------------------------------------------------- +# nodeSelector + +@test "client/DaemonSet: nodeSelector is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/DaemonSet: specified nodeSelector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.nodeSelector=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} + #-------------------------------------------------------------------- # priorityClassName diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index fec7d18ac3..5f58698c44 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -189,4 +189,37 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.serviceAccountName | contains("connect-injector-webhook-svc-account")' | tee /dev/stderr) [ "${actual}" = "true" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# nodeSelector + +@test "connectInject/Deployment: nodeSelector is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "connectInject/Deployment: nodeSelector is not set by default with sync enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "connectInject/Deployment: specified nodeSelector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.nodeSelector=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 10d711af45..d7031112cc 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -266,6 +266,28 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# nodeSelector + +@test "server/StatefulSet: nodeSelector is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/StatefulSet: specified nodeSelector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.nodeSelector=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} + #-------------------------------------------------------------------- # priorityClassName diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 224a0f4d8f..4be0a1c368 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -282,3 +282,36 @@ load _helpers yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# nodeSelector + +@test "syncCatalog/Deployment: nodeSelector is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "syncCatalog/Deployment: nodeSelector is not set by default with sync enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "syncCatalog/Deployment: specified nodeSelector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.nodeSelector=testing' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "testing" ] +} diff --git a/values.yaml b/values.yaml index a3c495779d..082c7dfacc 100644 --- a/values.yaml +++ b/values.yaml @@ -109,12 +109,6 @@ server: # - type: secret (or "configMap") # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul - - ## server node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - # tolerations: [] # Affinity Settings # Commenting out or setting as empty the affinity variable, will allow @@ -134,6 +128,13 @@ server: # in a PodSpec. tolerations: "" + # nodeSelector labels for server pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + nodeSelector: null + # used to assign priority to server pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" @@ -192,6 +193,13 @@ client: # - operator: "Exists" tolerations: "" + # nodeSelector labels for client pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + nodeSelector: null + # used to assign priority to client pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" @@ -210,13 +218,6 @@ client: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com - ## client tolerations for pod assignment - ## client node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - # tolerations: [] - # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns @@ -298,11 +299,12 @@ syncCatalog: secretName: null secretKey: null - ## syncCatalog node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - # tolerations: [] + # nodeSelector labels for syncCatalog pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + nodeSelector: null # ConnectInject will enable the automatic Connect sidecar injector. connectInject: @@ -345,8 +347,9 @@ connectInject: certName: tls.crt keyName: tls.key - ## connectInject node selectors and tolerations for pod assignment - ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector - # nodeSelector: {"beta.kubernetes.io/arch": "amd64"} - ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ - # tolerations: [] \ No newline at end of file + # nodeSelector labels for connectInject pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + nodeSelector: null From 46a95a4323f67b89a6786cfc11cf0d69f6e49533 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 21 Mar 2019 10:20:47 -0700 Subject: [PATCH 182/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 793fc9c4c3..248cc05bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ IMPROVEMENTS: * Support tolerations on Consul client and server pods * Support gossip protocol encryption * Allows custom environment variables for Consul client and server pods + * Support nodeSelectors for all components BUG FIXES: From 8afc84a6d6383f83d2331de5fa2b424e0bb79bbb Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 21 Mar 2019 11:38:03 -0700 Subject: [PATCH 183/739] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248cc05bf8..f2cebcdb6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ IMPROVEMENTS: - * Support pod priority classes for Consul servers and clients + * Support pod PriorityClasses for Consul servers and clients * Add annotation and additional spec values for the UI service * Add liveness and readiness checks to the catalog sync pod [[consul-k8s GH 57](https://github.com/hashicorp/consul-k8s/issues/57)] * Support custom annotations for Consul clients and servers * Support PodSecurityPolicies for Consul components * Add service accounts and cluster roles/role bindings for each Consul component + * Add the namespace to the metadata volume name * Support tolerations on Consul client and server pods * Support gossip protocol encryption * Allows custom environment variables for Consul client and server pods @@ -16,6 +17,7 @@ IMPROVEMENTS: BUG FIXES: * Allow setting `extraConfig` variables using Helm's `--set` flag [[GH 74](https://github.com/hashicorp/consul-helm/issues/74)] + * Fix a formatting bug in the enterprise license command ## 0.6.0 (February 8, 2019) From 0f7ccd2a3d37d46b014c9b5aca974ac175c7c346 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 21 Mar 2019 11:50:58 -0700 Subject: [PATCH 184/739] Update versions for a release --- Chart.yaml | 2 +- values.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Chart.yaml b/Chart.yaml index c6d59c9842..1e55e63805 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.6.0 +version: 0.7.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index 082c7dfacc..4065c838ef 100644 --- a/values.yaml +++ b/values.yaml @@ -16,7 +16,7 @@ global: # Examples: # image: "consul:1.4.2" # image: "consul:1.4.2-ent" # Enterprise Consul image - image: "consul:1.4.2" + image: "consul:1.4.4" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden @@ -24,7 +24,7 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - imageK8S: "hashicorp/consul-k8s:0.6.0" + imageK8S: "hashicorp/consul-k8s:0.7.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 1fd05f3d7b4e65310d1e412b5defab409167a94a Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 21 Mar 2019 12:08:23 -0700 Subject: [PATCH 185/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2cebcdb6b..96b08376d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## UNRELEASED +## 0.7.0 (March 21, 2019) + IMPROVEMENTS: * Support pod PriorityClasses for Consul servers and clients From 5eb5cb91d9b493603e202e361ffc5fb5e5d3fc44 Mon Sep 17 00:00:00 2001 From: Alvin Huang Date: Mon, 25 Mar 2019 19:39:33 -0400 Subject: [PATCH 186/739] fix consul-enterprise image ref --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 4065c838ef..3ccd299252 100644 --- a/values.yaml +++ b/values.yaml @@ -15,7 +15,7 @@ global: # # Examples: # image: "consul:1.4.2" - # image: "consul:1.4.2-ent" # Enterprise Consul image + # image: "hashicorp/consul-enterprise:1.4.2-ent" # Enterprise Consul image image: "consul:1.4.4" # imageK8S is the name (and tag) of the consul-k8s Docker image that From a82b569481978f37965a5835206f772a5f0c7772 Mon Sep 17 00:00:00 2001 From: Sarah Christoff Date: Mon, 29 Apr 2019 17:48:21 -0500 Subject: [PATCH 187/739] Add consulPrefix Option Adds consulPrefix option to allow users to update k8s service names with a prefix when they are registered in Consul catalog. --- templates/sync-catalog-deployment.yaml | 5 ++++- test/unit/sync-catalog-deployment.bats | 24 ++++++++++++++++++++++++ values.yaml | 6 ++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 8cabb09b04..6b13868082 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -73,8 +73,11 @@ spec: -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} \ {{- end }} {{- if .Values.syncCatalog.k8sTag }} - -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} + -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} \ {{- end }} + {{- if .Values.syncCatalog.consulPrefix}} + -consul-service-prefix="{{ .Values.syncCatalog.consulPrefix}}" \ + {{- end}} livenessProbe: httpGet: path: /health/ready diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 4be0a1c368..7e16bc1e97 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -174,6 +174,30 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# consulPrefix + +@test "syncCatalog/Deployment: no consulPrefix by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-service-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: can specify consulPrefix" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.consulPrefix=foo-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-service-prefix=\"foo-\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # k8sTag diff --git a/values.yaml b/values.yaml index 3ccd299252..63f6f057fe 100644 --- a/values.yaml +++ b/values.yaml @@ -274,6 +274,12 @@ syncCatalog: # prepended with "consul-". (Consul -> Kubernetes sync) k8sPrefix: null + # consulPrefix is the service prefix which preprends itself + # to Kubernetes services registered within Consul + # For example, "k8s-" will register all services peprended with "k8s-". + # (Kubernetes -> Consul sync) + consulPrefix: null + # k8sTag is an optional tag that is applied to all of the Kubernetes services # that are synced into Consul. If nothing is set, defaults to "k8s". # (Kubernetes -> Consul sync) From 25bd147a83fef659074e02aae36005eefea37028 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 1 May 2019 09:11:14 -0700 Subject: [PATCH 188/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96b08376d0..8c7fa22ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## UNRELEASED +IMPROVEMENTS: + + * Support adding a prefix to Kubernetes services registered in Consul [[GH 140](https://github.com/hashicorp/consul-helm/issues/140)] + ## 0.7.0 (March 21, 2019) IMPROVEMENTS: From bd81254690ee2c00cabe315f54488c63dfc4b4a6 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 3 Apr 2019 16:51:23 -0700 Subject: [PATCH 189/739] Implementation `bootstrapACLs` option This new config option allows folks creating an entire Consul cluster (both servers and clients, optionally catalog sync) in Kubernetes to automatically enable ACLs and bootstrap the system with server, client and (optionally) catalog sync tokens. It does this by applying a `server-acl-init` job after the servers have started up to bootstrap the servers and create client and sync tokens that are written to Kubernetes secrets. The client and sync pods have an init container when this option is enabled that waits for these secrets to be populated, then applies them once they become available. Manual creation of other ACL tokens is possible by extracting the original bootstrap token out of its Kubernetes secret and connecting directly to a Consul server. At the moment, the secrets are not automatically cleaned up when the Helm chart is deleted. So, like PersistentVolumeClaims, these will need to be manually deleted. --- templates/NOTES.txt | 7 ++ templates/client-clusterrole.yaml | 13 ++- templates/client-daemonset.yaml | 27 +++++++ templates/connect-inject-deployment.yaml | 2 + templates/server-acl-init-clusterrole.yaml | 27 +++++++ .../server-acl-init-clusterrolebinding.yaml | 23 ++++++ templates/server-acl-init-job.yaml | 56 +++++++++++++ templates/server-acl-init-serviceaccount.yaml | 16 ++++ templates/server-config-configmap.yaml | 11 +++ templates/sync-catalog-clusterrole.yaml | 9 +++ templates/sync-catalog-deployment.yaml | 20 +++++ test/unit/client-clusterrole.bats | 40 ++++++++++ test/unit/client-daemonset.bats | 57 +++++++++++++ test/unit/server-acl-init-clusterrole.bats | 44 +++++++++++ .../server-acl-init-clusterrolebinding.bats | 44 +++++++++++ test/unit/server-acl-init-job.bats | 79 +++++++++++++++++++ test/unit/server-acl-init-serviceaccount.bats | 44 +++++++++++ test/unit/server-configmap.bats | 10 +++ test/unit/sync-catalog-clusterrole.bats | 28 +++++++ test/unit/sync-catalog-deployment.bats | 31 ++++++++ values.yaml | 6 ++ 21 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 templates/server-acl-init-clusterrole.yaml create mode 100644 templates/server-acl-init-clusterrolebinding.yaml create mode 100644 templates/server-acl-init-job.yaml create mode 100644 templates/server-acl-init-serviceaccount.yaml create mode 100644 test/unit/server-acl-init-clusterrole.bats create mode 100644 test/unit/server-acl-init-clusterrolebinding.bats create mode 100644 test/unit/server-acl-init-job.bats create mode 100644 test/unit/server-acl-init-serviceaccount.bats diff --git a/templates/NOTES.txt b/templates/NOTES.txt index 377cca03c9..26d90c9ed5 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -11,3 +11,10 @@ Your release is named {{ .Release.Name }}. To learn more about the release, try: $ helm status {{ .Release.Name }} $ helm get {{ .Release.Name }} + + +{{- if (and .Values.global.bootstrapACLs (gt (len .Values.server.extraConfig) 3)) }} +Warning: Defining server extraConfig potentially disrupts the automatic ACL + bootstrapping required settings. This may cause future issues if + there are conflicts. +{{- end }} diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index 0e84b59e7e..d06e1fcc3e 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -8,8 +8,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.enablePodSecurityPolicies }} +{{- if (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }} rules: +{{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] resourceNames: @@ -17,4 +19,13 @@ rules: verbs: - use {{- end }} +{{- if .Values.global.bootstrapACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ .Release.Name }}-consul-client-acl-token + verbs: + - get +{{- end }} {{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 0fdca74a7e..4746366bb2 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -61,6 +61,10 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} + {{- if .Values.global.bootstrapACLs }} + - name: aclconfig + emptyDir: {} + {{- end }} containers: - name: consul @@ -106,6 +110,9 @@ spec: -config-dir=/consul/userconfig/{{ .name }} \ {{- end }} {{- end }} + {{- if .Values.global.bootstrapACLs}} + -config-dir=/consul/aclconfig \ + {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} @@ -133,6 +140,10 @@ spec: readOnly: true mountPath: /consul/userconfig/{{ .name }} {{- end }} + {{- if .Values.global.bootstrapACLs}} + - name: aclconfig + mountPath: /consul/aclconfig + {{- end }} lifecycle: preStop: exec: @@ -173,6 +184,22 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} + {{- if .Values.global.bootstrapACLs }} + initContainers: + - name: client-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ .Release.Name }}-consul-client-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="client" + volumeMounts: + - name: aclconfig + mountPath: /consul/aclconfig + {{- end }} {{- if .Values.client.nodeSelector }} nodeSelector: {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 8bcfb68125..12d2222297 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -25,6 +25,8 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: connect-injector + annotations: + "consul.hashicorp.com/connect-inject": "false" spec: {{- if not .Values.connectInject.certs.secretName }} serviceAccountName: {{ template "consul.fullname" . }}-connect-injector-webhook-svc-account diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml new file mode 100644 index 0000000000..09fba1410b --- /dev/null +++ b/templates/server-acl-init-clusterrole.yaml @@ -0,0 +1,27 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - list + - apiGroups: [""] + resources: + - secrets + verbs: + - create + - get +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml new file mode 100644 index 0000000000..2506dc79a9 --- /dev/null +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -0,0 +1,23 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-server-acl-init +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml new file mode 100644 index 0000000000..f47c300f6b --- /dev/null +++ b/templates/server-acl-init-job.yaml @@ -0,0 +1,56 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server-acl-init + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init + containers: + - name: post-install-job + image: {{ .Values.global.imageK8S }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s server-acl-init \ + -release-name={{ .Release.Name }} \ + -k8s-namespace={{ .Release.Namespace }} \ + -expected-replicas={{ .Values.server.replicas }} \ + {{- if .Values.syncCatalog.enabled }} + -create-sync-token=true \ + {{- end }} + {{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }} + -allow-dns=true + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml new file mode 100644 index 0000000000..f254a3c429 --- /dev/null +++ b/templates/server-acl-init-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index b0f9ea198d..d55eff7a06 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -13,4 +13,15 @@ metadata: data: extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} + {{- if .Values.global.bootstrapACLs }} + acl-config.json: | + { + "acl": { + "enabled": true, + "default_policy": "deny", + "down_policy": "extend-cache", + "enable_token_persistence": true + } + } + {{- end }} {{- end }} diff --git a/templates/sync-catalog-clusterrole.yaml b/templates/sync-catalog-clusterrole.yaml index b30dad4e60..90bc051abb 100644 --- a/templates/sync-catalog-clusterrole.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -27,6 +27,15 @@ rules: - nodes verbs: - get +{{- if .Values.global.bootstrapACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ .Release.Name }}-consul-catalog-sync-acl-token + verbs: + - get +{{- end }} {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 6b13868082..37a376eca6 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -48,6 +48,13 @@ spec: name: {{ .Values.syncCatalog.aclSyncToken.secretName }} key: {{ .Values.syncCatalog.aclSyncToken.secretKey }} {{- end }} + {{- if .Values.global.bootstrapACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-consul-catalog-sync-acl-token" + key: "token" + {{- end}} command: - "/bin/sh" - "-ec" @@ -98,6 +105,19 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 + {{- if .Values.global.bootstrapACLs }} + initContainers: + - name: sync-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ .Release.Name }}-consul-catalog-sync-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" + {{- end }} {{- if .Values.syncCatalog.nodeSelector }} nodeSelector: {{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }} diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats index 13ded5fec8..a279bfbcb6 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-clusterrole.bats @@ -51,3 +51,43 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "client/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "client/ClusterRole: allows secret access with global.bootsrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} + +@test "client/ClusterRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[1].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 6dfdae8a5b..7394e35869 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -418,3 +418,60 @@ load _helpers yq -r '.[4].value' | tee /dev/stderr) [ "${actual}" = "custom_no_proxy" ] } + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "client/DaemonSet: aclconfig volume is created when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[2].name == "aclconfig"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: aclconfig volumeMount is created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[2]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "aclconfig" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/aclconfig" ] +} + +@test "client/DaemonSet: command includes aclconfig dir when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("/consul/aclconfig"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: init container is created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "client-acl-init" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats new file mode 100644 index 0000000000..f3dc033dfb --- /dev/null +++ b/test/unit/server-acl-init-clusterrole.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInit/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ClusterRole: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRole: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ClusterRole: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats new file mode 100644 index 0000000000..29fd35501c --- /dev/null +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInit/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ClusterRoleBinding: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRoleBinding: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ClusterRoleBinding: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats new file mode 100644 index 0000000000..3e149b904a --- /dev/null +++ b/test/unit/server-acl-init-job.bats @@ -0,0 +1,79 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInit/Job: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# dns + +@test "serverACLInit/Job: dns acl option enabled with with .dns.enabled=-" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: dns acl option enabled with with .dns.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'dns.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: dns acl option disabled with with .dns.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'dns.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats new file mode 100644 index 0000000000..a9f4e6b645 --- /dev/null +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInit/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ServiceAccount: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ServiceAccount: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/ServiceAccount: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index 43eb2547ac..f001a60743 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -51,3 +51,13 @@ load _helpers yq '.data["extra-from-values.json"] | match("world") | length' | tee /dev/stderr) [ ! -z "${actual}" ] } + +@test "server/ConfigMap: creates acl config with .global.bootstrapACLs enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.data["acl-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/sync-catalog-clusterrole.bats b/test/unit/sync-catalog-clusterrole.bats index b816971d9f..85e79cf508 100755 --- a/test/unit/sync-catalog-clusterrole.bats +++ b/test/unit/sync-catalog-clusterrole.bats @@ -51,3 +51,31 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "syncCatalog/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-clusterrole.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[2].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "syncCatalog/ClusterRole: allows secret access with global.bootsrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-clusterrole.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules[2].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 7e16bc1e97..acb397f601 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -339,3 +339,34 @@ load _helpers yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) [ "${actual}" = "testing" ] } + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "syncCatalog/Deployment: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: init container is created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "client-acl-init" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 63f6f057fe..dd07931872 100644 --- a/values.yaml +++ b/values.yaml @@ -46,6 +46,12 @@ global: secretName: null secretKey: null + # bootstrapACLs will automatically create and assign ACL tokens within + # the Consul cluster. This currently requires enabling both servers and + # clients within Kubernetes. Additionally requires Consul v1.4+ and + # consul-k8s v0.8.0+. + bootstrapACLs: false + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From 67edcd34ae553d552516e36549061fc29d96dc9d Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 1 May 2019 10:15:40 -0700 Subject: [PATCH 190/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c7fa22ac9..13972f5065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ IMPROVEMENTS: * Support adding a prefix to Kubernetes services registered in Consul [[GH 140](https://github.com/hashicorp/consul-helm/issues/140)] + * Support an option for automatically bootstrapping ACLs in a Consul cluster that is run fully in Kubernetes. ## 0.7.0 (March 21, 2019) From ed43ecdb18d0b00a09494b30c4098409bc7e3fbb Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 23 Apr 2019 11:17:51 -0700 Subject: [PATCH 191/739] Support auth method in connect-inject Updates the server-acl-init job to also register Kuberentes as an auth method for Connect. Additionally adds an init container for the connect injection deployment to wait for the resultant acl token to be available in a Kubernetes secret. Updates rbac resources to use v1 instead of the beta tag. Removes the helper method that stopped name duplication if the release is explicitly named `consul`, since this breaks several necessary naming assumptions. --- templates/_helpers.tpl | 4 -- templates/client-clusterrole.yaml | 2 +- templates/client-clusterrolebinding.yaml | 2 +- ...connect-inject-authmethod-clusterrole.yaml | 19 ++++++++ ...-inject-authmethod-clusterrolebinding.yaml | 39 ++++++++++++++++ ...nect-inject-authmethod-serviceaccount.yaml | 14 ++++++ templates/connect-inject-clusterrole.yaml | 2 +- .../connect-inject-clusterrolebinding.yaml | 2 +- templates/connect-inject-deployment.yaml | 5 ++- templates/server-acl-init-clusterrole.yaml | 12 +++++ .../server-acl-init-clusterrolebinding.yaml | 2 +- templates/server-acl-init-job.yaml | 8 +++- templates/server-clusterrole.yaml | 2 +- templates/server-clusterrolebinding.yaml | 2 +- test/terraform/service-account.yaml | 2 +- ...connect-inject-authmethod-clusterrole.bats | 45 +++++++++++++++++++ ...-inject-authmethod-clusterrolebinding.bats | 45 +++++++++++++++++++ ...nect-inject-authmethod-serviceaccount.bats | 45 +++++++++++++++++++ test/unit/server-acl-init-job.bats | 25 +++++++++++ values.yaml | 6 +++ 20 files changed, 269 insertions(+), 14 deletions(-) create mode 100644 templates/connect-inject-authmethod-clusterrole.yaml create mode 100644 templates/connect-inject-authmethod-clusterrolebinding.yaml create mode 100644 templates/connect-inject-authmethod-serviceaccount.yaml create mode 100644 test/unit/connect-inject-authmethod-clusterrole.bats create mode 100644 test/unit/connect-inject-authmethod-clusterrolebinding.bats create mode 100644 test/unit/connect-inject-authmethod-serviceaccount.bats diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 3b5484d50d..7333b4ab01 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -9,13 +9,9 @@ be used as a full name. {{- .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. diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index d06e1fcc3e..671c7071bf 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ template "consul.fullname" . }}-client diff --git a/templates/client-clusterrolebinding.yaml b/templates/client-clusterrolebinding.yaml index e1061660dc..d769b24504 100644 --- a/templates/client-clusterrolebinding.yaml +++ b/templates/client-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ template "consul.fullname" . }}-client diff --git a/templates/connect-inject-authmethod-clusterrole.yaml b/templates/connect-inject-authmethod-clusterrole.yaml new file mode 100644 index 0000000000..07a295b898 --- /dev/null +++ b/templates/connect-inject-authmethod-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-role + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: + - apiGroups: [""] + resources: + - serviceaccounts + verbs: + - get +{{- end }} +{{- end }} diff --git a/templates/connect-inject-authmethod-clusterrolebinding.yaml b/templates/connect-inject-authmethod-clusterrolebinding.yaml new file mode 100644 index 0000000000..d88df03305 --- /dev/null +++ b/templates/connect-inject-authmethod-clusterrolebinding.yaml @@ -0,0 +1,39 @@ +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-authdelegator-role-binding + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "system:auth-delegator" +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-serviceaccount-role-binding + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-role +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/templates/connect-inject-authmethod-serviceaccount.yaml b/templates/connect-inject-authmethod-serviceaccount.yaml new file mode 100644 index 0000000000..e9c91d7929 --- /dev/null +++ b/templates/connect-inject-authmethod-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 32029d6b1f..036068b150 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -1,6 +1,6 @@ # The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration. {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ template "consul.fullname" . }}-connect-injector-webhook diff --git a/templates/connect-inject-clusterrolebinding.yaml b/templates/connect-inject-clusterrolebinding.yaml index 0da9587e0c..f22f2e7af6 100644 --- a/templates/connect-inject-clusterrolebinding.yaml +++ b/templates/connect-inject-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ template "consul.fullname" . }}-connect-injector-webhook-admin-role-binding diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 12d2222297..b45ccf4cd0 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -52,8 +52,11 @@ spec: -envoy-image="{{ .Values.connectInject.imageEnvoy }}" \ {{ end -}} -listen=:8080 \ + {{- if .Values.global.bootstrapACLs }} + -acl-auth-method="{{ .Release.Name }}-consul-k8s-auth-method" \ + {{- end }} {{- if .Values.connectInject.certs.secretName }} - -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} + -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \ -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} {{- else }} -tls-auto=${CONSUL_FULLNAME}-connect-injector-cfg \ diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 09fba1410b..b5c901e8e1 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -22,6 +22,18 @@ rules: verbs: - create - get +{{- if .Values.connectInject.enabled }} + - apiGroups: [""] + resources: + - serviceaccounts + verbs: + - get + - apiGroups: [""] + resources: + - services + verbs: + - get +{{- end }} {{- end }} {{- end }} {{- end }} \ No newline at end of file diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index 2506dc79a9..017b7097e9 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,7 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ template "consul.fullname" . }}-server-acl-init diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index f47c300f6b..04a9b170be 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -49,7 +49,13 @@ spec: -create-sync-token=true \ {{- end }} {{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }} - -allow-dns=true + -allow-dns=true \ + {{- end }} + {{- if .Values.connectInject.enabled }} + -create-inject-token=true \ + {{- end }} + {{- if .Values.connectInject.aclBindingRuleSelector }} + -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} {{- end }} {{- end }} {{- end }} diff --git a/templates/server-clusterrole.yaml b/templates/server-clusterrole.yaml index 93e2557384..fde7e00a68 100644 --- a/templates/server-clusterrole.yaml +++ b/templates/server-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ template "consul.fullname" . }}-server diff --git a/templates/server-clusterrolebinding.yaml b/templates/server-clusterrolebinding.yaml index 0e3010f4cd..b81f8c387d 100644 --- a/templates/server-clusterrolebinding.yaml +++ b/templates/server-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ template "consul.fullname" . }}-server diff --git a/test/terraform/service-account.yaml b/test/terraform/service-account.yaml index 05d1846b04..4dc90f66e3 100644 --- a/test/terraform/service-account.yaml +++ b/test/terraform/service-account.yaml @@ -4,7 +4,7 @@ metadata: name: helm namespace: kube-system --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: helm diff --git a/test/unit/connect-inject-authmethod-clusterrole.bats b/test/unit/connect-inject-authmethod-clusterrole.bats new file mode 100644 index 0000000000..6c5b2774cf --- /dev/null +++ b/test/unit/connect-inject-authmethod-clusterrole.bats @@ -0,0 +1,45 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInjectAuthMethod/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ClusterRole: enabled with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrole.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInjectAuthMethod/ClusterRole: disabled with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ClusterRole: enabled with global.bootstrapACLs.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-authmethod-clusterrolebinding.bats b/test/unit/connect-inject-authmethod-clusterrolebinding.bats new file mode 100644 index 0000000000..54ee11c8d8 --- /dev/null +++ b/test/unit/connect-inject-authmethod-clusterrolebinding.bats @@ -0,0 +1,45 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInjectAuthMethod/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ClusterRoleBinding: enabled with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInjectAuthMethod/ClusterRoleBinding: disabled with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ClusterRoleBinding: enabled with global.bootstrapACLs.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-authmethod-serviceaccount.bats b/test/unit/connect-inject-authmethod-serviceaccount.bats new file mode 100644 index 0000000000..1089ab35a4 --- /dev/null +++ b/test/unit/connect-inject-authmethod-serviceaccount.bats @@ -0,0 +1,45 @@ +#!/usr/bin/env bats + +load _helpers + +@test "connectInjectAuthMethod/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ServiceAccount: enabled with global.enabled false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-serviceaccount.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInjectAuthMethod/ServiceAccount: disabled with connectInject.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-serviceaccount.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInjectAuthMethod/ServiceAccount: enabled with global.bootstrapACLs.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-authmethod-serviceaccount.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 3e149b904a..b748060364 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -77,3 +77,28 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# aclBindingRuleSelector/global.bootstrapACLs + +@test "serverACLInit/Job: no acl-binding-rule-selector flag by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'connectInject.aclBindingRuleSlector=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: can specify acl-binding-rule-selector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'connectInject.aclBindingRuleSelector="foo"' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-binding-rule-selector=\"foo\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index dd07931872..50abb02bc5 100644 --- a/values.yaml +++ b/values.yaml @@ -365,3 +365,9 @@ connectInject: # nodeSelector: | # beta.kubernetes.io/arch: amd64 nodeSelector: null + + # aclBindingRuleSelector is a string that defines the automatic binding + # rule to control the allowed authentication for Connect injection. The + # default disallows using the default service account for ACl generation. + # Requires Consul v1.5+ and consul-k8s v0.8.0+. + aclBindingRuleSelector: "serviceaccount.name!=default" From 0f06ea6859f30fe7c5e434b92f68da18825e2f4c Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 1 May 2019 15:19:16 -0700 Subject: [PATCH 192/739] Support the option to create an enterprise license acl token When bootstraACLs is enabled, this adds an init container to the enterprise license job that will wait until the appropriate acl token is populated. Additionally, it marks it to run after the acl init job so that everything is ready for it. --- templates/enterprise-license-clusterrole.yaml | 25 ++++++ ...enterprise-license-clusterrolebinding.yaml | 25 ++++++ .../enterprise-license-serviceaccount.yaml | 18 ++++ templates/enterprise-license.yaml | 33 ++++++-- templates/server-acl-init-job.yaml | 7 +- test/unit/enterprise-license-clusterrole.bats | 82 +++++++++++++++++++ ...enterprise-license-clusterrolebinding.bats | 82 +++++++++++++++++++ .../enterprise-license-serviceaccount.bats | 82 +++++++++++++++++++ test/unit/enterprise-license.bats | 34 ++++++++ test/unit/server-acl-init-job.bats | 42 +++++++++- test/unit/sync-catalog-deployment.bats | 7 +- 11 files changed, 423 insertions(+), 14 deletions(-) create mode 100644 templates/enterprise-license-clusterrole.yaml create mode 100644 templates/enterprise-license-clusterrolebinding.yaml create mode 100644 templates/enterprise-license-serviceaccount.yaml create mode 100644 test/unit/enterprise-license-clusterrole.bats create mode 100644 test/unit/enterprise-license-clusterrolebinding.bats create mode 100644 test/unit/enterprise-license-serviceaccount.bats diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-clusterrole.yaml new file mode 100644 index 0000000000..6d2bb86ed3 --- /dev/null +++ b/templates/enterprise-license-clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ .Release.Name }}-consul-enterprise-license-acl-token + verbs: + - get +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/enterprise-license-clusterrolebinding.yaml b/templates/enterprise-license-clusterrolebinding.yaml new file mode 100644 index 0000000000..4726cfff0c --- /dev/null +++ b/templates/enterprise-license-clusterrolebinding.yaml @@ -0,0 +1,25 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-enterprise-license +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/enterprise-license-serviceaccount.yaml b/templates/enterprise-license-serviceaccount.yaml new file mode 100644 index 0000000000..5d7d735c05 --- /dev/null +++ b/templates/enterprise-license-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index 8616a396d3..ee48b0deaa 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -14,7 +14,7 @@ metadata: release: {{ .Release.Name }} annotations: "helm.sh/hook": post-install - "helm.sh/hook-weight": "0" + "helm.sh/hook-weight": "100" "helm.sh/hook-delete-policy": hook-succeeded spec: template: @@ -30,21 +30,42 @@ spec: component: license spec: restartPolicy: Never - + serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license containers: - - name: post-install-job - image: "appropriate/curl" + - name: apply-enterprise-license + image: "{{ default .Values.global.image .Values.server.image }}" env: - name: ENTERPRISE_LICENSE valueFrom: secretKeyRef: name: {{ .Values.server.enterpriseLicense.secretName }} key: {{ .Values.server.enterpriseLicense.secretKey }} + - name: CONSUL_HTTP_ADDR + value: http://{{ template "consul.fullname" . }}-server:8500 + {{- if .Values.global.bootstrapACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-consul-enterprise-license-acl-token" + key: "token" + {{- end}} command: - "/bin/sh" - "-ec" - | - curl -fsSL -X PUT http://{{ template "consul.fullname" . }}-server:8500/v1/operator/license \ - --data ${ENTERPRISE_LICENSE} + consul license put "${ENTERPRISE_LICENSE}" + {{- if .Values.global.bootstrapACLs }} + initContainers: + - name: ent-license-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ .Release.Name }}-consul-enterprise-license-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" + {{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 04a9b170be..bee56037aa 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -44,7 +44,6 @@ spec: consul-k8s server-acl-init \ -release-name={{ .Release.Name }} \ -k8s-namespace={{ .Release.Namespace }} \ - -expected-replicas={{ .Values.server.replicas }} \ {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ {{- end }} @@ -55,8 +54,12 @@ spec: -create-inject-token=true \ {{- end }} {{- if .Values.connectInject.aclBindingRuleSelector }} - -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} + -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \ {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + -create-enterprise-license-token=true \ + {{- end }} + -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} {{- end }} diff --git a/test/unit/enterprise-license-clusterrole.bats b/test/unit/enterprise-license-clusterrole.bats new file mode 100644 index 0000000000..5d80c42c26 --- /dev/null +++ b/test/unit/enterprise-license-clusterrole.bats @@ -0,0 +1,82 @@ +#!/usr/bin/env bats + +load _helpers + +@test "enterpriseLicense/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: disabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: disabled when ent secretName missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: disabled when ent secretKey missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRole: can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/enterprise-license-clusterrolebinding.bats b/test/unit/enterprise-license-clusterrolebinding.bats new file mode 100644 index 0000000000..3d15169610 --- /dev/null +++ b/test/unit/enterprise-license-clusterrolebinding.bats @@ -0,0 +1,82 @@ +#!/usr/bin/env bats + +load _helpers + +@test "enterpriseLicense/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: disabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: disabled when ent secretName missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: disabled when ent secretKey missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ClusterRoleBinding: can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/enterprise-license-serviceaccount.bats b/test/unit/enterprise-license-serviceaccount.bats new file mode 100644 index 0000000000..c247419f84 --- /dev/null +++ b/test/unit/enterprise-license-serviceaccount.bats @@ -0,0 +1,82 @@ +#!/usr/bin/env bats + +load _helpers + +@test "enterpriseLicense/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: disabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: disabled when ent secretName missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: disabled when ent secretKey missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/ServiceAccount: can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/enterprise-license.bats b/test/unit/enterprise-license.bats index 6da9c0892a..b32acc4048 100644 --- a/test/unit/enterprise-license.bats +++ b/test/unit/enterprise-license.bats @@ -53,3 +53,37 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "server/EnterpriseLicense: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/EnterpriseLicense: init container is created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "ent-license-acl-init" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index b748060364..9da6a7291b 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -46,7 +46,7 @@ load _helpers #-------------------------------------------------------------------- # dns -@test "serverACLInit/Job: dns acl option enabled with with .dns.enabled=-" { +@test "serverACLInit/Job: dns acl option enabled with .dns.enabled=-" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -56,7 +56,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/Job: dns acl option enabled with with .dns.enabled=true" { +@test "serverACLInit/Job: dns acl option enabled with .dns.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -67,7 +67,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/Job: dns acl option disabled with with .dns.enabled=false" { +@test "serverACLInit/Job: dns acl option disabled with .dns.enabled=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -101,4 +101,40 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-acl-binding-rule-selector=\"foo\""))' | tee /dev/stderr) [ "${actual}" = "true" ] + +#-------------------------------------------------------------------- +# enterpriseLicense + +@test "serverACLInit/Job: ent license acl option enabled with server.enterpriseLicense.secretName and server.enterpriseLicense.secretKey set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: ent license acl option disabled missing server.enterpriseLicense.secretName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: ent license acl option disabled missing server.enterpriseLicense.secretKey" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] } diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index acb397f601..5f7179681b 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -354,17 +354,18 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: init container is created when global.bootstrapACLs=true" { +@test "syncCatalog/Deployment: init container is created when global.bootstrapACLs=true" { cd `chart_dir` local object=$(helm template \ - -x templates/client-daemonset.yaml \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ --set 'global.bootstrapACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) local actual=$(echo $object | yq -r '.name' | tee /dev/stderr) - [ "${actual}" = "client-acl-init" ] + [ "${actual}" = "sync-acl-init" ] local actual=$(echo $object | yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) From 11c9c224005eaa9a1be405d4d767473a5621cbc4 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 2 May 2019 16:53:11 -0700 Subject: [PATCH 193/739] Support central configuration and proxy defaults Added in Consul 1.5, proxy defaults allow users to define config options that will be automatically applied to all injected sidecar proxies. Additionally, it is possible to enable Connect services to be centrally registered. --- templates/client-config-configmap.yaml | 6 +++ templates/connect-inject-deployment.yaml | 6 +++ templates/server-config-configmap.yaml | 23 ++++++++++- test/unit/client-configmap.bats | 24 ++++++++++++ test/unit/connect-inject-deployment.bats | 47 ++++++++++++++++++++++ test/unit/server-configmap.bats | 50 ++++++++++++++++++++++++ values.yaml | 17 ++++++++ 7 files changed, 172 insertions(+), 1 deletion(-) diff --git a/templates/client-config-configmap.yaml b/templates/client-config-configmap.yaml index 001158982e..e96f50ff30 100644 --- a/templates/client-config-configmap.yaml +++ b/templates/client-config-configmap.yaml @@ -14,4 +14,10 @@ metadata: data: extra-from-values.json: |- {{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }} + {{- if (and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled) }} + central-config.json: |- + { + "enable_central_service_config": true + } + {{- end }} {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index b45ccf4cd0..aefcebe78c 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -55,6 +55,12 @@ spec: {{- if .Values.global.bootstrapACLs }} -acl-auth-method="{{ .Release.Name }}-consul-k8s-auth-method" \ {{- end }} + {{- if .Values.connectInject.centralConfig.enabled }} + -enable-central-config=true \ + {{- end }} + {{- if (and .Values.connectInject.centralConfig.enabled .Values.connectInject.centralConfig.defaultProtocol) }} + -default-protocol="{{ .Values.connectInject.centralConfig.defaultProtocol }}" \ + {{- end }} {{- if .Values.connectInject.certs.secretName }} -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \ -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index d55eff7a06..c07521ff08 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -14,7 +14,7 @@ data: extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} {{- if .Values.global.bootstrapACLs }} - acl-config.json: | + acl-config.json: |- { "acl": { "enabled": true, @@ -24,4 +24,25 @@ data: } } {{- end }} + {{- if (and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled) }} + central-config.json: |- + { + "enable_central_service_config": true + } + {{- if gt (len .Values.connectInject.centralConfig.proxyDefaults) 3 }} + proxy-defaults-config.json: |- + { + "config_entries": { + "bootstrap": [ + { + "kind": "proxy-defaults", + "name": "global", + "config": +{{ tpl .Values.connectInject.centralConfig.proxyDefaults . | trimAll "\"" | indent 14 }} + } + ] + } + } + {{- end }} + {{- end }} {{- end }} diff --git a/test/unit/client-configmap.bats b/test/unit/client-configmap.bats index 13cd65406a..f50bbdd331 100755 --- a/test/unit/client-configmap.bats +++ b/test/unit/client-configmap.bats @@ -51,3 +51,27 @@ load _helpers yq '.data["extra-from-values.json"] | match("world") | length' | tee /dev/stderr) [ ! -z "${actual}" ] } + +#-------------------------------------------------------------------- +# connectInject.centralConfig + +@test "client/ConfigMap: centralConfig is disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/ConfigMap: centralConfig can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + . | tee /dev/stderr | + yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 5f58698c44..fd60a4dd61 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -223,3 +223,50 @@ load _helpers yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) [ "${actual}" = "testing" ] } + +#-------------------------------------------------------------------- +# centralConfig + +@test "connectInject/Deployment: centralConfig is disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-enable-central-config"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: centralConfig can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-enable-central-config"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: defaultProtocol is disabled by default with centralConfig enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-default-protocol"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: defaultProtocol can be enabled with centralConfig enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.defaultProtocol=grpc' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-default-protocol=\"grpc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index f001a60743..354afde166 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -52,6 +52,9 @@ load _helpers [ ! -z "${actual}" ] } +#-------------------------------------------------------------------- +# global.bootstrapACLs + @test "server/ConfigMap: creates acl config with .global.bootstrapACLs enabled" { cd `chart_dir` local actual=$(helm template \ @@ -61,3 +64,50 @@ load _helpers yq '.data["acl-config.json"] | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# connectInject.centralConfig + +@test "server/ConfigMap: centralConfig is disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: centralConfig can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + . | tee /dev/stderr | + yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/ConfigMap: proxyDefaults disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + . | tee /dev/stderr | + yq '.data["proxy-defaults-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ConfigMap: proxyDefaults can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ + . | tee /dev/stderr | + yq '.data["proxy-defaults-config.json"] | match("world") | length' | tee /dev/stderr) + [ ! -z "${actual}" ] +} diff --git a/values.yaml b/values.yaml index 50abb02bc5..18f8df36a3 100644 --- a/values.yaml +++ b/values.yaml @@ -371,3 +371,20 @@ connectInject: # default disallows using the default service account for ACl generation. # Requires Consul v1.5+ and consul-k8s v0.8.0+. aclBindingRuleSelector: "serviceaccount.name!=default" + + # Requires Consul v1.5+ and consul-k8s v0.8.0+ + centralConfig: + enabled: false + + # defaultProtocol allows you to specify a convenience default protocol if + # all of your service are of the same protocol type. The individual annotation + # on any given pod will override this value. A protocol must be provided, + # either through this setting or individual annotation, for a service to be + # registered correctly. Valid values are "http", "http2", "grpc" and "tcp". + defaultProtocol: null + + # proxyDefaults is a raw json string that will be applied to all Connect + # proxy sidecar pods that can include any valid configuration for the + # configured proxy. + proxyDefaults: | + {} From bea94384e8204234509f304e0ffcb73d55bd42e9 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 May 2019 13:18:41 -0700 Subject: [PATCH 194/739] Update values.yaml Co-Authored-By: adilyse --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 18f8df36a3..7528b245bd 100644 --- a/values.yaml +++ b/values.yaml @@ -377,7 +377,7 @@ connectInject: enabled: false # defaultProtocol allows you to specify a convenience default protocol if - # all of your service are of the same protocol type. The individual annotation + # most of your services are of the same protocol type. The individual annotation # on any given pod will override this value. A protocol must be provided, # either through this setting or individual annotation, for a service to be # registered correctly. Valid values are "http", "http2", "grpc" and "tcp". From 1a83488e9bda2841d69220c58bc8c485be0cd6e1 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 6 May 2019 13:43:05 -0700 Subject: [PATCH 195/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13972f5065..3bbb293b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ IMPROVEMENTS: * Support adding a prefix to Kubernetes services registered in Consul [[GH 140](https://github.com/hashicorp/consul-helm/issues/140)] * Support an option for automatically bootstrapping ACLs in a Consul cluster that is run fully in Kubernetes. + * Support central service configuration including proxy defaults in Connect (available in Consul 1.5+). ## 0.7.0 (March 21, 2019) From b63abbb5075e0c970761754b04043302d32f59ad Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 6 May 2019 14:04:31 -0700 Subject: [PATCH 196/739] Add missing curly brace --- test/unit/server-acl-init-job.bats | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 9da6a7291b..2c9beca80d 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -101,6 +101,7 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-acl-binding-rule-selector=\"foo\""))' | tee /dev/stderr) [ "${actual}" = "true" ] +} #-------------------------------------------------------------------- # enterpriseLicense From b77c9c72e1eb065d2f6d6cfa8feda34462889104 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Tue, 7 May 2019 10:42:44 -0700 Subject: [PATCH 197/739] Update expected server name in acceptance tests To deal with a naming issue, the removal of duplicate `consul` prefixes in the naming of things was updated. This updates the acceptance test names to follow the new convention. --- test/acceptance/server.bats | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/acceptance/server.bats b/test/acceptance/server.bats index dc358f6303..0c81cd1568 100644 --- a/test/acceptance/server.bats +++ b/test/acceptance/server.bats @@ -4,10 +4,10 @@ load _helpers @test "server: default, comes up healthy" { helm_install - wait_for_ready $(name_prefix)-server-0 + wait_for_ready $(name_prefix)-consul-server-0 # Verify there are three servers - local server_count=$(kubectl exec "$(name_prefix)-server-0" consul members | + local server_count=$(kubectl exec "$(name_prefix)-consul-server-0" consul members | grep server | wc -l) [ "${server_count}" -eq "3" ] From 3fdd085a9b6757a99cb214b1f4a0f844297ef9b5 Mon Sep 17 00:00:00 2001 From: Todd Radel Date: Mon, 22 Apr 2019 13:23:31 -0400 Subject: [PATCH 198/739] Remove the "enabled" flag and test for secretName and keyName. --- templates/client-daemonset.yaml | 4 ++-- templates/server-statefulset.yaml | 4 ++-- test/unit/client-daemonset.bats | 6 ------ test/unit/server-statefulset.bats | 6 ------ values.yaml | 1 - 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 4746366bb2..52828257ac 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -82,7 +82,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} - name: GOSSIP_KEY valueFrom: secretKeyRef: @@ -115,7 +115,7 @@ spec: {{- end }} -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ - {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} -encrypt="${GOSSIP_KEY}" \ {{- end }} {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 09d7488c28..6552fea8b7 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -81,7 +81,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} - name: GOSSIP_KEY valueFrom: secretKeyRef: @@ -109,7 +109,7 @@ spec: -datacenter={{ .Values.global.datacenter }} \ -data-dir=/consul/data \ -domain={{ .Values.global.domain }} \ - {{- if (and .Values.global.gossipEncryption.enabled .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} -encrypt="${GOSSIP_KEY}" \ {{- end }} {{- if .Values.server.connect }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 7394e35869..a77695ec07 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -326,7 +326,6 @@ load _helpers local actual=$(helm template \ -x templates/client-daemonset.yaml \ --set 'client.enabled=false' \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretName=foo' \ --set 'global.gossipEncryption.secretKey=bar' \ . | tee /dev/stderr | @@ -338,7 +337,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=bar' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) @@ -349,7 +347,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretName=foo' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) @@ -360,7 +357,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=foo' \ --set 'global.gossipEncryption.secretName=bar' \ . | tee /dev/stderr | @@ -372,7 +368,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -382,7 +377,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=foo' \ --set 'global.gossipEncryption.secretName=bar' \ . | tee /dev/stderr | diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index d7031112cc..35df8c4c4c 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -371,7 +371,6 @@ load _helpers local actual=$(helm template \ -x templates/enterprise-license.yaml \ --set 'server.enabled=false' \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretName=foo' \ --set 'global.gossipEncryption.secretKey=bar' \ . | tee /dev/stderr | @@ -383,7 +382,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=bar' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) @@ -394,7 +392,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretName=foo' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .env[] | select(.name == "GOSSIP_KEY") | length > 0' | tee /dev/stderr) @@ -405,7 +402,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=foo' \ --set 'global.gossipEncryption.secretName=bar' \ . | tee /dev/stderr | @@ -417,7 +413,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -427,7 +422,6 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'global.gossipEncryption.enabled=true' \ --set 'global.gossipEncryption.secretKey=foo' \ --set 'global.gossipEncryption.secretName=bar' \ . | tee /dev/stderr | diff --git a/values.yaml b/values.yaml index 7528b245bd..97e9976e45 100644 --- a/values.yaml +++ b/values.yaml @@ -42,7 +42,6 @@ global: # key with the "consul keygen" command. # See https://www.consul.io/docs/commands/keygen.html gossipEncryption: - enabled: false secretName: null secretKey: null From 7d2f13bceb807ad90c097ed0eac9ad1839a304b2 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 8 May 2019 11:25:47 -0700 Subject: [PATCH 199/739] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bbb293b22..ef130fca1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ IMPROVEMENTS: * Support adding a prefix to Kubernetes services registered in Consul [[GH 140](https://github.com/hashicorp/consul-helm/issues/140)] * Support an option for automatically bootstrapping ACLs in a Consul cluster that is run fully in Kubernetes. * Support central service configuration including proxy defaults in Connect (available in Consul 1.5+). + * Remove the `gossipEncryption.enabled` option and instead have the implementation based on the existence of the secretName and secretKey. ## 0.7.0 (March 21, 2019) From b49e039875eb00336563122eb64238df3b268139 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 8 May 2019 13:57:07 -0700 Subject: [PATCH 200/739] Prepare chart for release --- CHANGELOG.md | 4 +++- Chart.yaml | 2 +- values.yaml | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef130fca1b..f0b0db09a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ ## UNRELEASED +## 0.8.0 (May 8, 2019) + IMPROVEMENTS: * Support adding a prefix to Kubernetes services registered in Consul [[GH 140](https://github.com/hashicorp/consul-helm/issues/140)] - * Support an option for automatically bootstrapping ACLs in a Consul cluster that is run fully in Kubernetes. + * Support an option for automatically bootstrapping ACLs in a Consul cluster that is run fully in Kubernetes. If connectInject is enabled with this option on, this also automatically configures a new Kubernetes AuthMethod so that injected services are automatically granted ACL tokens based on their Kubernetes service account. * Support central service configuration including proxy defaults in Connect (available in Consul 1.5+). * Remove the `gossipEncryption.enabled` option and instead have the implementation based on the existence of the secretName and secretKey. diff --git a/Chart.yaml b/Chart.yaml index 1e55e63805..9e88613a61 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.7.0 +version: 0.8.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index 97e9976e45..b05d6fd2c2 100644 --- a/values.yaml +++ b/values.yaml @@ -14,9 +14,9 @@ global: # servers below. This can be overridden per component. # # Examples: - # image: "consul:1.4.2" - # image: "hashicorp/consul-enterprise:1.4.2-ent" # Enterprise Consul image - image: "consul:1.4.4" + # image: "consul:1.5.0" + # image: "hashicorp/consul-enterprise:1.5.0-ent" # Enterprise Consul image + image: "consul:1.5.0" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden @@ -24,7 +24,7 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - imageK8S: "hashicorp/consul-k8s:0.7.0" + imageK8S: "hashicorp/consul-k8s:0.8.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From ac6ece5d1272ba52627f9e7b230107cee3a784ed Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 9 May 2019 14:36:38 -0700 Subject: [PATCH 201/739] Update for v0.8.1 release --- CHANGELOG.md | 6 ++++++ Chart.yaml | 2 +- values.yaml | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0b0db09a1..8f2575f905 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## UNRELEASED +## 0.8.1 (May 9, 2019) + +IMPROVEMENTS: + + * Update default consul-k8s version to 0.8.1 for a central config bug fix + ## 0.8.0 (May 8, 2019) IMPROVEMENTS: diff --git a/Chart.yaml b/Chart.yaml index 9e88613a61..729266697e 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.8.0 +version: 0.8.1 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index b05d6fd2c2..8ea1ee6723 100644 --- a/values.yaml +++ b/values.yaml @@ -24,7 +24,7 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - imageK8S: "hashicorp/consul-k8s:0.8.0" + imageK8S: "hashicorp/consul-k8s:0.8.1" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running @@ -371,7 +371,7 @@ connectInject: # Requires Consul v1.5+ and consul-k8s v0.8.0+. aclBindingRuleSelector: "serviceaccount.name!=default" - # Requires Consul v1.5+ and consul-k8s v0.8.0+ + # Requires Consul v1.5+ and consul-k8s v0.8.1+ centralConfig: enabled: false From 4e181976179b16e42a910c36b4cb829908673636 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 16 May 2019 16:40:40 -0700 Subject: [PATCH 202/739] Make service account on ent license job optional If ACLs are not enabled, the enterprise license application job does not need any special privileges. This makes the definition of the service account in that spec key off of the `bootstrapACLs` value rather than being blanket applied. --- templates/enterprise-license.yaml | 2 ++ test/unit/enterprise-license.bats | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index ee48b0deaa..5bb2fcf4c5 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -30,7 +30,9 @@ spec: component: license spec: restartPolicy: Never + {{- if .Values.global.bootstrapACLs }} serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license + {{- end }} containers: - name: apply-enterprise-license image: "{{ default .Values.global.image .Values.server.image }}" diff --git a/test/unit/enterprise-license.bats b/test/unit/enterprise-license.bats index b32acc4048..5071f238e9 100644 --- a/test/unit/enterprise-license.bats +++ b/test/unit/enterprise-license.bats @@ -87,3 +87,26 @@ load _helpers yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "server/EnterpriseLicense: no service account specified when global.bootstrapACLS=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq '.spec.template.spec.serviceAccountName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/EnterpriseLicense: service account specified when global.bootstrapACLS=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.serviceAccountName | contains("consul-enterprise-license")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From 6fa9be91e5af25143c6ad98fab2d10fa7bdbfde4 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Fri, 17 May 2019 12:56:19 -0700 Subject: [PATCH 203/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f2575f905..43c43cb67a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## UNRELEASED +BUG FIXES: + + * Fix enterprise license application when ACLs are turned off + ## 0.8.1 (May 9, 2019) IMPROVEMENTS: From e213602eaa9de052689c67a36ce325dadb4d1bd8 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 7 Jun 2019 13:52:45 +0100 Subject: [PATCH 204/739] Ensure rules is always set. Fixes #178. The rules key must always be set, even if it's to be empty. --- templates/client-clusterrole.yaml | 4 +++- templates/server-clusterrole.yaml | 2 ++ test/unit/client-clusterrole.bats | 11 +++++++++++ test/unit/server-clusterrole.bats | 11 +++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index 671c7071bf..bb330147ee 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -10,7 +10,6 @@ metadata: release: {{ .Release.Name }} {{- if (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }} rules: -{{- end }} {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] @@ -28,4 +27,7 @@ rules: verbs: - get {{- end }} +{{- else}} +rules: [] +{{- end }} {{- end }} diff --git a/templates/server-clusterrole.yaml b/templates/server-clusterrole.yaml index fde7e00a68..e58d964f74 100644 --- a/templates/server-clusterrole.yaml +++ b/templates/server-clusterrole.yaml @@ -16,5 +16,7 @@ rules: - {{ template "consul.fullname" . }}-server verbs: - use +{{- else }} +rules: [] {{- end }} {{- end }} diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats index a279bfbcb6..3519e70485 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-clusterrole.bats @@ -52,6 +52,17 @@ load _helpers [ "${actual}" = "true" ] } +# The rules key must always be set (#178). +@test "client/ClusterRole: rules empty with client.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq '.rules' | tee /dev/stderr) + [ "${actual}" = "[]" ] +} + #-------------------------------------------------------------------- # global.enablePodSecurityPolicies diff --git a/test/unit/server-clusterrole.bats b/test/unit/server-clusterrole.bats index de8d1a9974..37b37dea93 100644 --- a/test/unit/server-clusterrole.bats +++ b/test/unit/server-clusterrole.bats @@ -51,3 +51,14 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +# The rules key must always be set (#178). +@test "server/ClusterRole: rules empty with server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq '.rules' | tee /dev/stderr) + [ "${actual}" = "[]" ] +} From e247cc0c68c064f86fc355471e4581092686b985 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 7 Jun 2019 13:50:40 +0100 Subject: [PATCH 205/739] Make test prereqs clearer --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 694627ee97..20b524b49a 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,22 @@ The Helm chart ships with both unit and acceptance tests. The unit tests don't require any active Kubernetes cluster and complete very quickly. These should be used for fast feedback during development. The acceptance tests require a Kubernetes cluster with a configured `kubectl`. -Both require [Bats](https://github.com/bats-core/bats-core) and `helm` to be -installed and available on the CLI. The unit tests also require the correct -version of [yq](https://pypi.org/project/yq/) if running locally. +### Prequisites +* [Bats](https://github.com/bats-core/bats-core) + ```bash + brew install bats-core + ``` +* [yq](https://pypi.org/project/yq/) + ```bash + brew install python-yq + ``` +* [helm](https://helm.sh) + ```bash + brew install kubernetes-helm + ``` + +### Running The Tests To run the unit tests: bats ./test/unit From 57ba3605dabe334b7b9278f970c2a2f63eeb730c Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 6 Jun 2019 18:24:28 -0700 Subject: [PATCH 206/739] Support running snapshot agents from the Helm chart This allows users to run the Consul Enterprise Snapshot Agents feature from the Helm chart. The snapshot agent uses the same permissions and affinities as the Consul clients because they need to be co-located. The configuration for the snapshot agents need to be defined in a Kubernetes secret. This must not include the `http_addr` field as it will conflict with the routing that is automatically set up to allow the snapshot agent to talk to the client on the same k8s node. Likewise, if ACLs are enabled using the `global.bootstrapACLs` option, the `token` field cannot be included either, since it is automatically populated. This also assumes that the snapshot agent retains its defaults of: "service": "consul-snapshot", "lock_key": "consul-snapshot/lock" Additionally, any cloud storage defined must be routable from the Kubernetes cluster where the snapshot agents are running. --- templates/client-clusterrole.yaml | 3 + .../client-snapshot-agent-deployment.yaml | 116 ++++++++++ templates/server-acl-init-job.yaml | 3 + test/unit/client-clusterrole.bats | 28 +++ .../client-snapshot-agent-deployment.bats | 206 ++++++++++++++++++ test/unit/server-acl-init-job.bats | 24 ++ values.yaml | 21 ++ 7 files changed, 401 insertions(+) create mode 100644 templates/client-snapshot-agent-deployment.yaml create mode 100644 test/unit/client-snapshot-agent-deployment.bats diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index bb330147ee..0264d6a191 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -24,6 +24,9 @@ rules: - secrets resourceNames: - {{ .Release.Name }}-consul-client-acl-token + {{- if .Values.client.snapshotAgent.enabled }} + - {{ .Release.Name }}-consul-client-snapshot-agent-acl-token + {{- end }} verbs: - get {{- end }} diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml new file mode 100644 index 0000000000..7d6ef5305c --- /dev/null +++ b/templates/client-snapshot-agent-deployment.yaml @@ -0,0 +1,116 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.client.snapshotAgent.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + replicas: {{ .Values.client.snapshotAgent.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client-snapshot-agent + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client-snapshot-agent + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + {{- if .Values.client.tolerations }} + tolerations: + {{ tpl .Values.client.tolerations . | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" . }}-client + + {{- if .Values.client.priorityClassName }} + priorityClassName: {{ .Values.client.priorityClassName | quote }} + {{- end }} + {{- if (or .Values.global.bootstrapACLs (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} + volumes: + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + - name: snapshot-config + secret: + secretName: {{ .Values.client.snapshotAgent.configSecret.secretName }} + items: + - key: {{ .Values.client.snapshotAgent.configSecret.secretKey }} + path: snapshot-config.json + {{- end }} + {{- if .Values.global.bootstrapACLs }} + - name: aclconfig + emptyDir: {} + {{- end }} + {{- end }} + containers: + - name: consul-snapshot-agent + image: "{{ default .Values.global.image .Values.client.image }}" + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.global.bootstrapACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-consul-client-snapshot-agent-acl-token" + key: "token" + {{- end}} + command: + - "/bin/sh" + - "-ec" + - | + exec /bin/consul snapshot agent \ + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + -config-dir=/consul/config \ + {{- end }} + {{- if .Values.global.bootstrapACLs}} + -config-dir=/consul/aclconfig \ + {{- end }} + -http-addr=http://${HOST_IP}:8500 + {{- if (or .Values.global.bootstrapACLs (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} + volumeMounts: + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + - name: snapshot-config + readOnly: true + mountPath: /consul/config + {{- end }} + {{- if .Values.global.bootstrapACLs}} + - name: aclconfig + mountPath: /consul/aclconfig + {{- end }} + {{- end }} + {{- if .Values.global.bootstrapACLs }} + initContainers: + - name: client-snapshot-agent-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ .Release.Name }}-consul-client-snapshot-agent-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" + volumeMounts: + - name: aclconfig + mountPath: /consul/aclconfig + {{- end }} + {{- if .Values.client.nodeSelector }} + nodeSelector: + {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index bee56037aa..ffc229946f 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -59,6 +59,9 @@ spec: {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} -create-enterprise-license-token=true \ {{- end }} + {{- if .Values.client.snapshotAgent.enabled }} + -create-snapshot-agent-token=true \ + {{- end }} -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats index 3519e70485..27ca407746 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-clusterrole.bats @@ -102,3 +102,31 @@ load _helpers yq -r '.rules[1].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] } + +#-------------------------------------------------------------------- +# client.snapshotAgent + +@test "client/ClusterRole: allows snapshot agent secret access with global.bootsrapACLs=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resourceNames | any(contains("-consul-client-snapshot-agent-acl-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/ClusterRole: allows snapshot agent secret access with global.bootsrapACLs=true, global.enablePodSecurityPolicies=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq -r '.rules[1].resourceNames | any(contains("-consul-client-snapshot-agent-acl-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats new file mode 100644 index 0000000000..a13ae943c3 --- /dev/null +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -0,0 +1,206 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/SnapshotAgentDeployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: enabled with client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.enabled=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: disabled with client=false and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# tolerations + +@test "client/SnapshotAgentDeployment: no tolerations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: populates tolerations when client.tolerations is populated" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.tolerations=allow' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations | contains("allow")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# priorityClassName + +@test "client/SnapshotAgentDeployment: no priorityClassName by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.priorityClassName | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: populates priorityClassName when client.priorityClassName is populated" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.priorityClassName=allow' \ + . | tee /dev/stderr | + yq '.spec.template.spec.priorityClassName | contains("allow")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs and snapshotAgent.configSecret + +@test "client/SnapshotAgentDeployment: no initContainer by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/SnapshotAgentDeployment: populates initContainer when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: no volumes by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/SnapshotAgentDeployment: populates volumes when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: populates volumes when client.snapshotAgent.configSecret.secretName and client.snapshotAgent.configSecret secretKey are defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.snapshotAgent.configSecret.secretName=secret' \ + --set 'client.snapshotAgent.configSecret.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: no container volumeMounts by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "client/SnapshotAgentDeployment: populates container volumeMounts when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: populates container volumeMounts when client.snapshotAgent.configSecret.secretName and client.snapshotAgent.configSecret secretKey are defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.snapshotAgent.configSecret.secretName=secret' \ + --set 'client.snapshotAgent.configSecret.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# nodeSelector + +@test "client/SnapshotAgentDeployment: no nodeSelector by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentDeployment: populates nodeSelector when client.nodeSelector is populated" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.nodeSelector=allow' \ + . | tee /dev/stderr | + yq '.spec.template.spec.nodeSelector | contains("allow")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 2c9beca80d..182f6f01c0 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -139,3 +139,27 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# client.snapshotAgent + +@test "serverACLInit/Job: snapshot agent acl option disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: snapshot agent acl option enabled with .client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 8ea1ee6723..601c0b97ab 100644 --- a/values.yaml +++ b/values.yaml @@ -223,6 +223,27 @@ client: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com + # snaphotAgent contains settings for setting up and running snapshot agents + # within the Consul clusters. They are required to be co-located with Consul + # clients, so will inherit the clients' nodeSelector, tolerations and affinity. + # This is an Enterprise feature only. + snapshotAgent: + enabled: false + + # replicas determines how many snapshot agent pods are created + replicas: 2 + + # configSecret references a Kubernetes secret that should be manually created to + # contain the entire config to be used on the snapshot agent. This is the preferred + # method of configuration since there are usually storage credentials present. + # Snapshot agent config details: + # https://www.consul.io/docs/commands/snapshot/agent.html#config-file-options- + # To create a secret: + # https://kubernetes.io/docs/concepts/configuration/secret/#creating-a-secret-using-kubectl-create-secret + configSecret: + secretName: null + secretKey: null + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From 27bb7499bf01ec0c4e9f2c8425a5a567000a7e58 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 3 Jul 2019 18:40:40 -0700 Subject: [PATCH 207/739] Separate out a separate service account for the snapshot agent This includes the service account, pod security policy, cluster role and cluster role binding and all of their associated tests. --- templates/client-clusterrole.yaml | 3 - .../client-snapshot-agent-clusterrole.yaml | 36 ++++++++ ...ent-snapshot-agent-clusterrolebinding.yaml | 21 +++++ ...ient-snapshot-agent-podsecuritypolicy.yaml | 41 +++++++++ .../client-snapshot-agent-serviceaccount.yaml | 14 +++ test/unit/client-clusterrole.bats | 28 ------ .../client-snapshot-agent-clusterrole.bats | 87 +++++++++++++++++++ ...ent-snapshot-agent-clusterrolebinding.bats | 44 ++++++++++ ...ient-snapshot-agent-podsecuritypolicy.bats | 34 ++++++++ .../client-snapshot-agent-serviceaccount.bats | 44 ++++++++++ 10 files changed, 321 insertions(+), 31 deletions(-) create mode 100644 templates/client-snapshot-agent-clusterrole.yaml create mode 100644 templates/client-snapshot-agent-clusterrolebinding.yaml create mode 100644 templates/client-snapshot-agent-podsecuritypolicy.yaml create mode 100644 templates/client-snapshot-agent-serviceaccount.yaml create mode 100644 test/unit/client-snapshot-agent-clusterrole.bats create mode 100644 test/unit/client-snapshot-agent-clusterrolebinding.bats create mode 100644 test/unit/client-snapshot-agent-podsecuritypolicy.bats create mode 100644 test/unit/client-snapshot-agent-serviceaccount.bats diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index 0264d6a191..bb330147ee 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -24,9 +24,6 @@ rules: - secrets resourceNames: - {{ .Release.Name }}-consul-client-acl-token - {{- if .Values.client.snapshotAgent.enabled }} - - {{ .Release.Name }}-consul-client-snapshot-agent-acl-token - {{- end }} verbs: - get {{- end }} diff --git a/templates/client-snapshot-agent-clusterrole.yaml b/templates/client-snapshot-agent-clusterrole.yaml new file mode 100644 index 0000000000..c4411c8254 --- /dev/null +++ b/templates/client-snapshot-agent-clusterrole.yaml @@ -0,0 +1,36 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.client.snapshotAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if not (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }} +rules: [] +{{- else }} +rules: +{{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-snapshot-agent + verbs: + - use +{{- end }} +{{- if .Values.global.bootstrapACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ .Release.Name }}-consul-client-snapshot-agent-acl-token + verbs: + - get +{{- end }} +{{- else }} +{{- end }} +{{- end }} diff --git a/templates/client-snapshot-agent-clusterrolebinding.yaml b/templates/client-snapshot-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..b4a27555aa --- /dev/null +++ b/templates/client-snapshot-agent-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.client.snapshotAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-snapshot-agent +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-snapshot-agent + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/templates/client-snapshot-agent-podsecuritypolicy.yaml b/templates/client-snapshot-agent-podsecuritypolicy.yaml new file mode 100644 index 0000000000..88513a484c --- /dev/null +++ b/templates/client-snapshot-agent-podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }} +{{- if .Values.client.snapshotAgent.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/templates/client-snapshot-agent-serviceaccount.yaml b/templates/client-snapshot-agent-serviceaccount.yaml new file mode 100644 index 0000000000..8e734019bd --- /dev/null +++ b/templates/client-snapshot-agent-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.client.snapshotAgent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats index 27ca407746..3519e70485 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-clusterrole.bats @@ -102,31 +102,3 @@ load _helpers yq -r '.rules[1].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] } - -#-------------------------------------------------------------------- -# client.snapshotAgent - -@test "client/ClusterRole: allows snapshot agent secret access with global.bootsrapACLs=true and client.snapshotAgent.enabled=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ - --set 'client.enabled=true' \ - --set 'global.bootstrapACLs=true' \ - --set 'client.snapshotAgent.enabled=true' \ - . | tee /dev/stderr | - yq -r '.rules[0].resourceNames | any(contains("-consul-client-snapshot-agent-acl-token"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "client/ClusterRole: allows snapshot agent secret access with global.bootsrapACLs=true, global.enablePodSecurityPolicies=true and client.snapshotAgent.enabled=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ - --set 'client.enabled=true' \ - --set 'global.bootstrapACLs=true' \ - --set 'global.enablePodSecurityPolicies=true' \ - --set 'client.snapshotAgent.enabled=true' \ - . | tee /dev/stderr | - yq -r '.rules[1].resourceNames | any(contains("-consul-client-snapshot-agent-acl-token"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} diff --git a/test/unit/client-snapshot-agent-clusterrole.bats b/test/unit/client-snapshot-agent-clusterrole.bats new file mode 100644 index 0000000000..25fe077220 --- /dev/null +++ b/test/unit/client-snapshot-agent-clusterrole.bats @@ -0,0 +1,87 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/SnapshotAgentClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentClusterRole: enabled with client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentClusterRole: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentClusterRole: disabled with client=false and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "client/SnapshotAgentClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "client/SnapshotAgentClusterRole: allows secret access with global.bootsrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} + +@test "client/SnapshotAgentClusterRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrole.yaml \ + --set 'client.enabled=true' \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[1].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} diff --git a/test/unit/client-snapshot-agent-clusterrolebinding.bats b/test/unit/client-snapshot-agent-clusterrolebinding.bats new file mode 100644 index 0000000000..887d695872 --- /dev/null +++ b/test/unit/client-snapshot-agent-clusterrolebinding.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/SnapshotAgentClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentClusterRoleBinding: enabled with client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentClusterRoleBinding: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + --set 'client.enabled=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentClusterRoleBinding: disabled with client=false and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} \ No newline at end of file diff --git a/test/unit/client-snapshot-agent-podsecuritypolicy.bats b/test/unit/client-snapshot-agent-podsecuritypolicy.bats new file mode 100644 index 0000000000..6e34b003d9 --- /dev/null +++ b/test/unit/client-snapshot-agent-podsecuritypolicy.bats @@ -0,0 +1,34 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/SnapshotAgentPodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentPodSecurityPolicy: disabled with snapshot agent disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-podsecuritypolicy.yaml \ + --set 'client.snapshotAgent.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentPodSecurityPolicy: enabled with snapshot agent enabled global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-podsecuritypolicy.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/client-snapshot-agent-serviceaccount.bats b/test/unit/client-snapshot-agent-serviceaccount.bats new file mode 100644 index 0000000000..5e85e328e8 --- /dev/null +++ b/test/unit/client-snapshot-agent-serviceaccount.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "client/SnapshotAgentServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "client/SnapshotAgentServiceAccount: enabled with client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-serviceaccount.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentServiceAccount: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-serviceaccount.yaml \ + --set 'client.enabled=true' \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentServiceAccount: disabled with client=false and client.snapshotAgent.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-serviceaccount.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} From 791f0c0b1f604395f3394748c5ca72a51ae2ae54 Mon Sep 17 00:00:00 2001 From: Ljupcho Kotev Date: Thu, 11 Jul 2019 14:43:27 +0200 Subject: [PATCH 208/739] Add correct service account in snapshot agent deployment --- templates/client-snapshot-agent-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index 7d6ef5305c..14170c2523 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -33,7 +33,7 @@ spec: {{ tpl .Values.client.tolerations . | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: 10 - serviceAccountName: {{ template "consul.fullname" . }}-client + serviceAccountName: {{ template "consul.fullname" . }}-snapshot-agent {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} From 1b78a87868462cc13289204a3baabd4a6f9aa01d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 2 Jul 2019 14:05:29 -0400 Subject: [PATCH 209/739] Add new config for Connect Mesh Gateways. --- Chart.yaml | 2 +- templates/mesh-gateway-clusterrole.yaml | 34 ++ .../mesh-gateway-clusterrolebinding.yaml | 20 + templates/mesh-gateway-deployment.yaml | 172 ++++++ templates/mesh-gateway-podsecuritypolicy.yaml | 40 ++ templates/mesh-gateway-service.yaml | 33 ++ templates/mesh-gateway-serviceaccount.yaml | 13 + templates/server-acl-init-job.yaml | 3 + templates/server-config-configmap.yaml | 22 +- test/unit/mesh-gateway-clusterrole.bats | 77 +++ .../unit/mesh-gateway-clusterrolebinding.bats | 37 ++ test/unit/mesh-gateway-deployment.bats | 505 ++++++++++++++++++ test/unit/mesh-gateway-podsecuritypolicy.bats | 25 + test/unit/mesh-gateway-service.bats | 186 +++++++ test/unit/mesh-gateway-serviceaccount.bats | 25 + test/unit/server-acl-init-job.bats | 13 + test/unit/server-configmap.bats | 45 ++ values.yaml | 136 ++++- 18 files changed, 1384 insertions(+), 4 deletions(-) create mode 100644 templates/mesh-gateway-clusterrole.yaml create mode 100644 templates/mesh-gateway-clusterrolebinding.yaml create mode 100644 templates/mesh-gateway-deployment.yaml create mode 100644 templates/mesh-gateway-podsecuritypolicy.yaml create mode 100644 templates/mesh-gateway-service.yaml create mode 100644 templates/mesh-gateway-serviceaccount.yaml create mode 100644 test/unit/mesh-gateway-clusterrole.bats create mode 100644 test/unit/mesh-gateway-clusterrolebinding.bats create mode 100755 test/unit/mesh-gateway-deployment.bats create mode 100644 test/unit/mesh-gateway-podsecuritypolicy.bats create mode 100755 test/unit/mesh-gateway-service.bats create mode 100644 test/unit/mesh-gateway-serviceaccount.bats diff --git a/Chart.yaml b/Chart.yaml index 729266697e..a8d6f1fdf6 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.8.1 +version: 0.9.0-beta description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/templates/mesh-gateway-clusterrole.yaml b/templates/mesh-gateway-clusterrole.yaml new file mode 100644 index 0000000000..5279f7af9f --- /dev/null +++ b/templates/mesh-gateway-clusterrole.yaml @@ -0,0 +1,34 @@ +{{- if .Values.meshGateway.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} +rules: +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-mesh-gateway + verbs: + - use +{{- end }} +{{- if .Values.global.bootstrapACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ .Release.Name }}-consul-mesh-gateway-acl-token + verbs: + - get +{{- end }} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/templates/mesh-gateway-clusterrolebinding.yaml b/templates/mesh-gateway-clusterrolebinding.yaml new file mode 100644 index 0000000000..f8150ebb53 --- /dev/null +++ b/templates/mesh-gateway-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.meshGateway.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-mesh-gateway +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml new file mode 100644 index 0000000000..e44b3f2d9b --- /dev/null +++ b/templates/mesh-gateway-deployment.yaml @@ -0,0 +1,172 @@ +{{- if .Values.meshGateway.enabled }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + {{- if .Values.meshGateway.annotations }} + annotations: + {{- tpl .Values.meshGateway.annotations . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.meshGateway.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: mesh-gateway + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: mesh-gateway + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + {{- if .Values.meshGateway.affinity }} + affinity: + {{ tpl .Values.meshGateway.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.meshGateway.tolerations }} + tolerations: + {{ tpl .Values.meshGateway.tolerations . | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" . }}-mesh-gateway + volumes: + - name: consul-bin + emptyDir: {} + {{- if .Values.meshGateway.hostNetwork }} + hostNetwork: {{ .Values.meshGateway.hostNetwork }} + {{- end }} + {{- if .Values.meshGateway.dnsPolicy }} + dnsPolicy: {{ .Values.meshGateway.dnsPolicy }} + {{- end }} + initContainers: + # We use the Envoy image as our base image so we use an init container to + # copy the Consul binary to a shared directory that can be used when + # starting Envoy. + - name: copy-consul-bin + image: {{ .Values.global.image | quote }} + command: + - cp + - /bin/consul + - /consul-bin/consul + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + {{- if .Values.global.bootstrapACLs }} + # Wait for secret containing acl token to be ready. + # Doesn't do anything with it but when the main container starts we + # know that it's been created. + - name: mesh-gateway-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ .Release.Name }}-consul-mesh-gateway-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" + {{- end }} + containers: + - name: mesh-gateway + image: {{ .Values.meshGateway.imageEnvoy | quote }} + {{- if .Values.meshGateway.resources }} + resources: + {{ tpl .Values.meshGateway.resources . | nindent 12 | trim }} + {{- end }} + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- if .Values.global.bootstrapACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ .Release.Name }}-consul-mesh-gateway-acl-token" + key: "token" + {{- end}} + command: + # /bin/sh -c is needed so we can use the pod-specific environment + # variables. + - "/bin/sh" + - "-ec" + - | + exec /consul-bin/consul connect envoy \ + -mesh-gateway \ + -register \ + -address="${POD_IP}:{{ .Values.meshGateway.containerPort }}" \ + -http-addr="${HOST_IP}:8500" \ + -grpc-addr="${HOST_IP}:8502" \ + {{- if .Values.meshGateway.wanAddress.host }} + -wan-address="{{ .Values.meshGateway.wanAddress.host }}:{{ .Values.meshGateway.wanAddress.port }}" \ + {{- else if .Values.meshGateway.wanAddress.useNodeName }} + -wan-address="${NODE_NAME}:{{ .Values.meshGateway.wanAddress.port }}" \ + {{- else if .Values.meshGateway.wanAddress.useNodeIP }} + -wan-address="${HOST_IP}:{{ .Values.meshGateway.wanAddress.port }}" \ + {{- end }} + {{- if .Values.meshGateway.consulServiceName }} + {{- if .Values.global.bootstrapACLs }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }} + -service={{ .Values.meshGateway.consulServiceName | quote }} \ + {{- end }} + {{- if .Values.meshGateway.enableHealthChecks }} + livenessProbe: + tcpSocket: + port: {{ .Values.meshGateway.containerPort }} + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: {{ .Values.meshGateway.containerPort }} + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + {{- end }} + ports: + - name: gateway + containerPort: {{ .Values.meshGateway.containerPort }} + {{- if .Values.meshGateway.hostPort }} + hostPort: {{ .Values.meshGateway.hostPort }} + {{- end }} + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -http-addr=\"${HOST_IP}:8500\" -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""] + {{- if .Values.meshGateway.priorityClassName }} + priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} + {{- end }} + {{- if .Values.meshGateway.nodeSelector }} + nodeSelector: + {{ tpl .Values.meshGateway.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/templates/mesh-gateway-podsecuritypolicy.yaml b/templates/mesh-gateway-podsecuritypolicy.yaml new file mode 100644 index 0000000000..ced5735925 --- /dev/null +++ b/templates/mesh-gateway-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.global.enablePodSecurityPolicies .Values.meshGateway.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/templates/mesh-gateway-service.yaml b/templates/mesh-gateway-service.yaml new file mode 100644 index 0000000000..7bd7ec2acc --- /dev/null +++ b/templates/mesh-gateway-service.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.meshGateway.enabled .Values.meshGateway.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + {{- if .Values.meshGateway.service.annotations }} + annotations: + {{ tpl .Values.meshGateway.service.annotations . | nindent 4 | trim }} + {{- end }} +spec: + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: mesh-gateway + ports: + - name: gateway + port: {{ .Values.meshGateway.service.port }} + targetPort: {{ .Values.meshGateway.containerPort }} + {{- if .Values.meshGateway.service.nodePort }} + nodePort: {{ .Values.meshGateway.service.nodePort }} + {{- end}} + type: {{ .Values.meshGateway.service.type }} + {{- if .Values.meshGateway.service.additionalSpec }} + {{ tpl .Values.meshGateway.service.additionalSpec . | nindent 2 | trim }} + {{- end }} +{{- end }} diff --git a/templates/mesh-gateway-serviceaccount.yaml b/templates/mesh-gateway-serviceaccount.yaml new file mode 100644 index 0000000000..70e8d947ca --- /dev/null +++ b/templates/mesh-gateway-serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.meshGateway.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +{{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index ffc229946f..d1c261f308 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -53,6 +53,9 @@ spec: {{- if .Values.connectInject.enabled }} -create-inject-token=true \ {{- end }} + {{- if .Values.meshGateway.enabled }} + -create-mesh-gateway-token=true \ + {{- end }} {{- if .Values.connectInject.aclBindingRuleSelector }} -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \ {{- end }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index c07521ff08..e7c3f050aa 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -24,7 +24,7 @@ data: } } {{- end }} - {{- if (and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled) }} + {{- if and .Values.connectInject.enabled .Values.connectInject.centralConfig.enabled }} central-config.json: |- { "enable_central_service_config": true @@ -37,12 +37,32 @@ data: { "kind": "proxy-defaults", "name": "global", + {{- if and .Values.meshGateway.enabled .Values.meshGateway.globalMode }} + "mesh_gateway": { + "mode": {{ .Values.meshGateway.globalMode | quote }} + }, + {{- end }} "config": {{ tpl .Values.connectInject.centralConfig.proxyDefaults . | trimAll "\"" | indent 14 }} } ] } } + {{- else if and .Values.meshGateway.enabled .Values.meshGateway.globalMode }} + proxy-defaults-config.json: |- + { + "config_entries": { + "bootstrap": [ + { + "kind": "proxy-defaults", + "name": "global", + "mesh_gateway": { + "mode": {{ .Values.meshGateway.globalMode | quote }} + } + } + ] + } + } {{- end }} {{- end }} {{- end }} diff --git a/test/unit/mesh-gateway-clusterrole.bats b/test/unit/mesh-gateway-clusterrole.bats new file mode 100644 index 0000000000..7d2b189ccb --- /dev/null +++ b/test/unit/mesh-gateway-clusterrole.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/ClusterRole: enabled with meshGateway.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/ClusterRole: rules for PodSecurityPolicy" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + + +@test "meshGateway/ClusterRole: rules for global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} + +@test "meshGateway/ClusterRole: rules is empty if no ACLs or PSPs" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.rules' | tee /dev/stderr) + [ "${actual}" = "[]" ] +} + +@test "meshGateway/ClusterRole: rules for both ACLs and PSPs" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules | length' | tee /dev/stderr) + [ "${actual}" = "2" ] +} diff --git a/test/unit/mesh-gateway-clusterrolebinding.bats b/test/unit/mesh-gateway-clusterrolebinding.bats new file mode 100644 index 0000000000..bc444c2c70 --- /dev/null +++ b/test/unit/mesh-gateway-clusterrolebinding.bats @@ -0,0 +1,37 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/ClusterRoleBinding: enabled with meshGateway.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrolebinding.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/ClusterRoleBinding: subject name is correct" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrolebinding.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.subjects[0].name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-mesh-gateway" ] +} + diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats new file mode 100755 index 0000000000..95183698dd --- /dev/null +++ b/test/unit/mesh-gateway-deployment.bats @@ -0,0 +1,505 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/Deployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/Deployment: enabled with meshGateway.enabled true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: fails if connectInject.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=false' \ + --set 'client.grpc=true' \ + --set 'client.grpc=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "connectInject.enabled must be true" ]] +} + +@test "meshGateway/Deployment: fails if client.grpc=false" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=false' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "client.grpc must be true" ]] +} + +@test "meshGateway/Deployment: no annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.annotations=key: value' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "meshGateway/Deployment: replicas defaults to 2" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.replicas' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "meshGateway/Deployment: replicas can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.replicas=3' \ + . | tee /dev/stderr | + yq -r '.spec.replicas' | tee /dev/stderr) + [ "${actual}" = "3" ] +} + +@test "meshGateway/Deployment: affinity defaults to one per node" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey' | tee /dev/stderr) + [ "${actual}" = "kubernetes.io/hostname" ] +} + +@test "meshGateway/Deployment: affinity can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.affinity=key: value' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.affinity.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "meshGateway/Deployment: no tolerations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.tolerations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: tolerations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.tolerations=- key: value' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.tolerations[0].key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "meshGateway/Deployment: hostNetwork can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.hostNetwork=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.hostNetwork' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: no dnsPolicy by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.dnsPolicy' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: dnsPolicy can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.dnsPolicy=ClusterFirst' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.dnsPolicy' | tee /dev/stderr) + [ "${actual}" = "ClusterFirst" ] +} + +@test "meshGateway/Deployment: global.BootstrapACLs enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr ) + local init_container=$(echo "${actual}" | yq -r '.spec.template.spec.initContainers[1].name' | tee /dev/stderr) + [ "${init_container}" = "mesh-gateway-acl-init" ] + + local secret=$(echo "${actual}" | yq -r '.spec.template.spec.containers[0].env[3].name' | tee /dev/stderr) + [ "${secret}" = "CONSUL_HTTP_TOKEN" ] +} + +@test "meshGateway/Deployment: envoy image has default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "envoyproxy/envoy:v1.10.0" ] +} + +@test "meshGateway/Deployment: envoy image can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.imageEnvoy=new/image' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "new/image" ] +} + +@test "meshGateway/Deployment: resources has default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + + [ $(echo "${actual}" | yq -r '.requests.memory') = "128Mi" ] + [ $(echo "${actual}" | yq -r '.requests.cpu') = "250m" ] + [ $(echo "${actual}" | yq -r '.limits.memory') = "256Mi" ] + [ $(echo "${actual}" | yq -r '.limits.cpu') = "500m" ] +} + +@test "meshGateway/Deployment: resources can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.resources=requests: yadayada' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.requests' | tee /dev/stderr) + [ "${actual}" = "yadayada" ] +} + +@test "meshGateway/Deployment: containerPort defaults to 443" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) + + [[ $(echo "$actual" | yq -r '.command[2]') =~ '-address="${POD_IP}:443"' ]] + [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "443" ] + [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "443" ] + [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "443" ] +} + +@test "meshGateway/Deployment: containerPort can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.containerPort=8443' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) + + [[ $(echo "$actual" | yq -r '.command[2]') =~ '-address="${POD_IP}:8443"' ]] + [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "8443" ] + [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "8443" ] + [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] +} + +@test "meshGateway/Deployment: wanAddress.port defaults to 443" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.wanAddress.useNodeIP=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + [[ "${actual}" =~ '-wan-address="${HOST_IP}:443"' ]] +} + +@test "meshGateway/Deployment: wanAddress uses NodeIP by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + [[ "${actual}" =~ '-wan-address="${HOST_IP}:443"' ]] +} + +@test "meshGateway/Deployment: wanAddress.useNodeIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.wanAddress.useNodeIP=true' \ + --set 'meshGateway.wanAddress.port=4444' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + [[ "${actual}" =~ '-wan-address="${HOST_IP}:4444"' ]] +} + +@test "meshGateway/Deployment: wanAddress.useNodeName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.wanAddress.useNodeIP=false' \ + --set 'meshGateway.wanAddress.useNodeName=true' \ + --set 'meshGateway.wanAddress.port=4444' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + [[ "${actual}" =~ '-wan-address="${NODE_NAME}:4444"' ]] +} + +@test "meshGateway/Deployment: wanAddress.host" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.wanAddress.useNodeIP=false' \ + --set 'meshGateway.wanAddress.useNodeName=false' \ + --set 'meshGateway.wanAddress.host=myhost' \ + --set 'meshGateway.wanAddress.port=4444' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + [[ "${actual}" =~ '-wan-address="myhost:4444"' ]] +} + +@test "meshGateway/Deployment: fails if consulServiceName is set and bootstrapACLs is true" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.consulServiceName=override' \ + --set 'global.bootstrapACLs=true' \ + . + [ "$status" -eq 1 ] + [[ "$output" =~ "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" ]] +} + +@test "meshGateway/Deployment: consulServiceName can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.consulServiceName=overridden' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) + + [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ '-service="overridden"' ]] + [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"overridden\"' ]] +} + +@test "meshGateway/Deployment: healthchecks are on by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) + + local liveness=$(echo "${actual}" | yq -r '.livenessProbe | length > 0' | tee /dev/stderr) + [ "${liveness}" = "true" ] + local readiness=$(echo "${actual}" | yq -r '.readinessProbe | length > 0' | tee /dev/stderr) + [ "${readiness}" = "true" ] +} + +@test "meshGateway/Deployment: can disable healthchecks" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.enableHealthChecks=false' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) + + local liveness=$(echo "${actual}" | yq -r '.livenessProbe | length > 0' | tee /dev/stderr) + [ "${liveness}" = "false" ] + local readiness=$(echo "${actual}" | yq -r '.readinessProbe | length > 0' | tee /dev/stderr) + [ "${readiness}" = "false" ] +} + +@test "meshGateway/Deployment: no hostPort by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].ports[0].hostPort' | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: can set a hostPort" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.hostPort=443' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].ports[0].hostPort' | tee /dev/stderr) + + [ "${actual}" = "443" ] +} + +@test "meshGateway/Deployment: no priorityClassName by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: can set a priorityClassName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.priorityClassName=name' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) + + [ "${actual}" = "name" ] +} + +@test "meshGateway/Deployment: no nodeSelector by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "meshGateway/Deployment: can set a nodeSelector" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.nodeSelector=key: value' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.nodeSelector.key' | tee /dev/stderr) + + [ "${actual}" = "value" ] +} diff --git a/test/unit/mesh-gateway-podsecuritypolicy.bats b/test/unit/mesh-gateway-podsecuritypolicy.bats new file mode 100644 index 0000000000..4e0dfed40f --- /dev/null +++ b/test/unit/mesh-gateway-podsecuritypolicy.bats @@ -0,0 +1,25 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/PodSecurityPolicy: enabled with meshGateway.enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-podsecuritypolicy.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/mesh-gateway-service.bats b/test/unit/mesh-gateway-service.bats new file mode 100755 index 0000000000..4264f0abca --- /dev/null +++ b/test/unit/mesh-gateway-service.bats @@ -0,0 +1,186 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/Service: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/Service: disabled with meshGateway.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/Service: enabled with meshGateway.enabled=true meshGateway.service.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Service: no annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "meshGateway/Service: can set annotations" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.annotations=key: value' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "meshGateway/Service: has default port" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].port' | tee /dev/stderr) + [ "${actual}" = "443" ] +} + +@test "meshGateway/Service: can set port" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.port=8443' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].port' | tee /dev/stderr) + [ "${actual}" = "8443" ] +} + +@test "meshGateway/Service: has default targetPort" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].targetPort' | tee /dev/stderr) + [ "${actual}" = "443" ] +} + +@test "meshGateway/Service: uses targetPort from containerPort" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.containerPort=8443' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].targetPort' | tee /dev/stderr) + [ "${actual}" = "8443" ] +} + +@test "meshGateway/Service: no nodePort by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "meshGateway/Service: can set a nodePort" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.nodePort=8443' \ + . | tee /dev/stderr | + yq -r '.spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "8443" ] +} + +@test "meshGateway/Service: defaults to type ClusterIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "ClusterIP" ] +} + +@test "meshGateway/Service: can set type" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] +} + +@test "meshGateway/Service: can add additionalSpec" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-service.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.additionalSpec=key: value' \ + . | tee /dev/stderr | + yq -r '.spec.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} diff --git a/test/unit/mesh-gateway-serviceaccount.bats b/test/unit/mesh-gateway-serviceaccount.bats new file mode 100644 index 0000000000..e6972222c5 --- /dev/null +++ b/test/unit/mesh-gateway-serviceaccount.bats @@ -0,0 +1,25 @@ +#!/usr/bin/env bats + +load _helpers + +@test "meshGateway/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "meshGateway/ServiceAccount: enabled with meshGateway.enabled = true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-serviceaccount.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 182f6f01c0..9b6209d2a4 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -163,3 +163,16 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "serverACLInit/Job: mesh gateway acl option enabled with .meshGateway.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-mesh-gateway-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index 354afde166..e95baa0836 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -111,3 +111,48 @@ load _helpers yq '.data["proxy-defaults-config.json"] | match("world") | length' | tee /dev/stderr) [ ! -z "${actual}" ] } + +@test "server/ConfigMap: proxyDefaults and meshGateways can be enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.globalMode=remote' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.data["proxy-defaults-config.json"]' | yq -r '.config_entries.bootstrap[0].mesh_gateway.mode' | tee /dev/stderr) + [ "${actual}" = "remote" ] +} + +@test "server/ConfigMap: proxyDefaults should have no gateway mode if disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.globalMode=' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.data["proxy-defaults-config.json"]' | yq '.config_entries.bootstrap[0].mesh_gateway' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: global gateway mode is set even if there are no proxyDefaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.proxyDefaults=""' \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.globalMode=remote' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.data["proxy-defaults-config.json"]' | yq -r '.config_entries.bootstrap[0].mesh_gateway.mode' | tee /dev/stderr) + [ "${actual}" = "remote" ] +} diff --git a/values.yaml b/values.yaml index 601c0b97ab..cadb75226b 100644 --- a/values.yaml +++ b/values.yaml @@ -24,7 +24,8 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - imageK8S: "hashicorp/consul-k8s:0.8.1" + # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. + imageK8S: "hashicorp/consul-k8s:0.9.0" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running @@ -167,7 +168,7 @@ client: join: null # grpc should be set to true if the gRPC listener should be enabled. - # This should be set to true if connectInject is enabled. + # This should be set to true if connectInject or meshGateway is enabled. grpc: false # Resource requests, limits, etc. for the client cluster placement. This @@ -408,3 +409,134 @@ connectInject: # configured proxy. proxyDefaults: | {} + +# Mesh Gateways enable Consul Connect to work across Consul datacenters. +meshGateway: + # If mesh gateways are enabled, a Deployment will be created that runs + # gateways and Consul Connect will be configured to use gateways. + # See https://www.consul.io/docs/connect/mesh_gateway.html + # Requirements: consul >= 1.6.0 and consul-k8s >= 0.8.2 if using global.bootstrapACLs. + enabled: false + + # Globally configure which mode the gateway should run in. + # Can be set to either "remote", "local", "none" or "". + # See https://consul.io/docs/connect/mesh_gateway.html#modes-of-operation for + # a description of each mode. + # If set, connectInject.centralConfig.enabled should be set to true so that + # the global config will actually be used. + # If set to the empty string, no global default will be set and the gateway mode + # will need to be set individually for each service. + globalMode: local + + # Number of replicas for the Deployment. + replicas: 2 + + # What gets registered as wan address for the gateway. + wanAddress: + # Port that gets registered. + port: 443 + + # If true, each Gateway Pod will advertise its NodeIP + # (as provided by the Kubernetes downward API) as the wan address. + # This is useful if the node IPs are routable from other DCs. + # useNodeName and host must be false and "" respectively. + useNodeIP: true + + # If true, each Gateway Pod will advertise its NodeName + # (as provided by the Kubernetes downward API) as the wan address. + # This is useful if the node names are DNS entries that are + # routable from other DCs. + # meshGateway.wanAddress.port will be used as the port for the wan address. + # useNodeIP and host must be false and "" respectively. + useNodeName: false + + # If set, each gateway Pod will use this host as its wan address. + # Users must ensure that this address routes to the Gateway pods, + # for example via a DNS entry that routes to the Service fronting the Deployment. + # meshGateway.wanAddress.port will be used as the port for the wan address. + # useNodeIP and useNodeName must be false. + host: "" + + # The service option configures the Service that fronts the Gateway Deployment. + service: + # Whether to create a Service or not. + enabled: false + + # Type of service, ex. LoadBalancer, ClusterIP. + type: ClusterIP + + # Port that the service will be exposed on. + # The targetPort will be set to meshGateway.containerPort. + port: 443 + + # Optional nodePort of the service. Can be used in conjunction with + # type: NodePort. + nodePort: null + + # Optional YAML string for additional annotations. + annotations: null + + # Optional YAML string that will be appended to the Service spec. + additionalSpec: null + + # Envoy image to use. + imageEnvoy: envoyproxy/envoy:v1.10.0 + + # If set to true, gateway Pods will run on the host network. + hostNetwork: false + + # dnsPolicy to use. + dnsPolicy: null + + # Override the default 'mesh-gateway' service name registered in Consul. + # Cannot be used if bootstrapACLs is true since the ACL token generated + # is only for the name 'mesh-gateway'. + consulServiceName: "" + + # Port that the gateway will run on inside the container. + containerPort: 443 + + # Optional hostPort for the gateway to be exposed on. + # This can be used with wanAddress.port and wanAddress.useNodeIP + # to expose the gateways directly from the node. + # If hostNetwork is true, this must be null or set to the same port as + # containerPort. + hostPort: null + + # If there are no connect-enabled services running, then the gateway + # will fail health checks. You may disable health checks as a temporary + # workaround. + enableHealthChecks: true + + resources: | + requests: + memory: "128Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "500m" + + # By default, we set an anti affinity so that two gateway pods won't be + # on the same node. NOTE: Gateways require that Consul client agents are + # also running on the nodes alongside each gateway Pod. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: mesh-gateway + topologyKey: kubernetes.io/hostname + + # Optional YAML string to specify tolerations. + tolerations: null + + # Optional YAML string to specify a nodeSelector config. + nodeSelector: null + + # Optional priorityClassName. + priorityClassName: "" + + # Optional YAML string for additional annotations. + annotations: null From 2987628f17af11737984aec9afc3492b6be62287 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 15 Jul 2019 14:49:13 +0100 Subject: [PATCH 210/739] Code review fixes --- templates/mesh-gateway-deployment.yaml | 15 +- test/unit/mesh-gateway-clusterrole.bats | 3 +- .../unit/mesh-gateway-clusterrolebinding.bats | 3 +- test/unit/mesh-gateway-deployment.bats | 132 ++++++++++++++++-- test/unit/mesh-gateway-podsecuritypolicy.bats | 2 +- test/unit/mesh-gateway-service.bats | 20 ++- test/unit/mesh-gateway-serviceaccount.bats | 2 +- test/unit/server-configmap.bats | 17 ++- values.yaml | 10 +- 9 files changed, 173 insertions(+), 31 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index e44b3f2d9b..adc6552123 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -1,6 +1,8 @@ {{- if .Values.meshGateway.enabled }} {{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} {{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} +{{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}} +{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} apiVersion: apps/v1 kind: Deployment metadata: @@ -12,10 +14,6 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway - {{- if .Values.meshGateway.annotations }} - annotations: - {{- tpl .Values.meshGateway.annotations . | nindent 4 }} - {{- end }} spec: replicas: {{ .Values.meshGateway.replicas }} selector: @@ -33,6 +31,9 @@ spec: component: mesh-gateway annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.meshGateway.annotations }} + {{- tpl .Values.meshGateway.annotations . | nindent 8 }} + {{- end }} spec: {{- if .Values.meshGateway.affinity }} affinity: @@ -100,10 +101,12 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP + {{- if .Values.meshGateway.wanAddress.useNodeName }} - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName + {{- end }} {{- if .Values.global.bootstrapACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: @@ -130,8 +133,8 @@ spec: {{- else if .Values.meshGateway.wanAddress.useNodeIP }} -wan-address="${HOST_IP}:{{ .Values.meshGateway.wanAddress.port }}" \ {{- end }} - {{- if .Values.meshGateway.consulServiceName }} - {{- if .Values.global.bootstrapACLs }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }} + {{- if and .Values.meshGateway.consulServiceName }} + {{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }} -service={{ .Values.meshGateway.consulServiceName | quote }} \ {{- end }} {{- if .Values.meshGateway.enableHealthChecks }} diff --git a/test/unit/mesh-gateway-clusterrole.bats b/test/unit/mesh-gateway-clusterrole.bats index 7d2b189ccb..1f3db8298e 100644 --- a/test/unit/mesh-gateway-clusterrole.bats +++ b/test/unit/mesh-gateway-clusterrole.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ClusterRole: enabled with meshGateway.enabled=true" { +@test "meshGateway/ClusterRole: enabled with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrole.yaml \ @@ -36,7 +36,6 @@ load _helpers [ "${actual}" = "podsecuritypolicies" ] } - @test "meshGateway/ClusterRole: rules for global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/mesh-gateway-clusterrolebinding.bats b/test/unit/mesh-gateway-clusterrolebinding.bats index bc444c2c70..92400bb31f 100644 --- a/test/unit/mesh-gateway-clusterrolebinding.bats +++ b/test/unit/mesh-gateway-clusterrolebinding.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ClusterRoleBinding: enabled with meshGateway.enabled=true" { +@test "meshGateway/ClusterRoleBinding: enabled with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrolebinding.yaml \ @@ -30,6 +30,7 @@ load _helpers --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ + --name 'release-name' \ . | tee /dev/stderr | yq -r '.subjects[0].name' | tee /dev/stderr) [ "${actual}" = "release-name-consul-mesh-gateway" ] diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 95183698dd..1e05287a05 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -11,27 +11,27 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/Deployment: enabled with meshGateway.enabled true" { +@test "meshGateway/Deployment: enabled with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# prerequisites + @test "meshGateway/Deployment: fails if connectInject.enabled=false" { cd `chart_dir` run helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=false' \ - --set 'client.grpc=true' \ --set 'client.grpc=true' . [ "$status" -eq 1 ] [[ "$output" =~ "connectInject.enabled must be true" ]] @@ -42,7 +42,6 @@ load _helpers run helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ --set 'client.grpc=false' \ --set 'connectInject.enabled=true' \ --set 'connectInject.centralConfig.enabled=true' . @@ -50,7 +49,37 @@ load _helpers [[ "$output" =~ "client.grpc must be true" ]] } -@test "meshGateway/Deployment: no annotations by default" { +@test "meshGateway/Deployment: fails if global.enabled is false and clients are not explicitly enabled" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'client.grpc=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'global.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +@test "meshGateway/Deployment: fails if global.enabled is true but clients are explicitly disabled" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'client.grpc=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'global.enabled=true' \ + --set 'client.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +#-------------------------------------------------------------------- +# annotations + +@test "meshGateway/Deployment: no extra annotations by default" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -58,23 +87,27 @@ load _helpers --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ . | tee /dev/stderr | - yq -r '.metadata.annotations' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq -r '.spec.template.metadata.annotations | length' | tee /dev/stderr) + [ "${actual}" = "1" ] } -@test "meshGateway/Deployment: annotations can be set" { +@test "meshGateway/Deployment: extra annotations can be set" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'meshGateway.annotations=key: value' \ + --set 'meshGateway.annotations=key1: value1 +key2: value2' \ . | tee /dev/stderr | - yq -r '.metadata.annotations.key' | tee /dev/stderr) - [ "${actual}" = "value" ] + yq -r '.spec.template.metadata.annotations | length' | tee /dev/stderr) + [ "${actual}" = "3" ] } +#-------------------------------------------------------------------- +# replicas + @test "meshGateway/Deployment: replicas defaults to 2" { cd `chart_dir` local actual=$(helm template \ @@ -100,6 +133,9 @@ load _helpers [ "${actual}" = "3" ] } +#-------------------------------------------------------------------- +# affinity + @test "meshGateway/Deployment: affinity defaults to one per node" { cd `chart_dir` local actual=$(helm template \ @@ -125,6 +161,9 @@ load _helpers [ "${actual}" = "value" ] } +#-------------------------------------------------------------------- +# tolerations + @test "meshGateway/Deployment: no tolerations by default" { cd `chart_dir` local actual=$(helm template \ @@ -150,6 +189,22 @@ load _helpers [ "${actual}" = "value" ] } +#-------------------------------------------------------------------- +# hostNetwork + + +@test "meshGateway/Deployment: hostNetwork is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.hostNetwork' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + @test "meshGateway/Deployment: hostNetwork can be set" { cd `chart_dir` local actual=$(helm template \ @@ -163,6 +218,9 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# dnsPolicy + @test "meshGateway/Deployment: no dnsPolicy by default" { cd `chart_dir` local actual=$(helm template \ @@ -188,7 +246,10 @@ load _helpers [ "${actual}" = "ClusterFirst" ] } -@test "meshGateway/Deployment: global.BootstrapACLs enabled" { +#-------------------------------------------------------------------- +# BootstrapACLs + +@test "meshGateway/Deployment: global.BootstrapACLs enabled creates init container and secret" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -200,10 +261,13 @@ load _helpers local init_container=$(echo "${actual}" | yq -r '.spec.template.spec.initContainers[1].name' | tee /dev/stderr) [ "${init_container}" = "mesh-gateway-acl-init" ] - local secret=$(echo "${actual}" | yq -r '.spec.template.spec.containers[0].env[3].name' | tee /dev/stderr) + local secret=$(echo "${actual}" | yq -r '.spec.template.spec.containers[0].env[2].name' | tee /dev/stderr) [ "${secret}" = "CONSUL_HTTP_TOKEN" ] } +#-------------------------------------------------------------------- +# envoyImage + @test "meshGateway/Deployment: envoy image has default" { cd `chart_dir` local actual=$(helm template \ @@ -229,6 +293,9 @@ load _helpers [ "${actual}" = "new/image" ] } +#-------------------------------------------------------------------- +# resources + @test "meshGateway/Deployment: resources has default" { cd `chart_dir` local actual=$(helm template \ @@ -258,6 +325,9 @@ load _helpers [ "${actual}" = "yadayada" ] } +#-------------------------------------------------------------------- +# containerPort + @test "meshGateway/Deployment: containerPort defaults to 443" { cd `chart_dir` local actual=$(helm template \ @@ -291,6 +361,9 @@ load _helpers [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] } +#-------------------------------------------------------------------- +# wanAddress + @test "meshGateway/Deployment: wanAddress.port defaults to 443" { cd `chart_dir` local actual=$(helm template \ @@ -361,6 +434,9 @@ load _helpers [[ "${actual}" =~ '-wan-address="myhost:4444"' ]] } +#-------------------------------------------------------------------- +# consulServiceName + @test "meshGateway/Deployment: fails if consulServiceName is set and bootstrapACLs is true" { cd `chart_dir` run helm template \ @@ -375,6 +451,22 @@ load _helpers [[ "$output" =~ "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" ]] } +@test "meshGateway/Deployment: does not fail if consulServiceName is set to mesh-gateway and bootstrapACLs is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.consulServiceName=mesh-gateway' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr \ + | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) + + [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ '-service="mesh-gateway"' ]] + [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"mesh-gateway\"' ]] +} + @test "meshGateway/Deployment: consulServiceName can be set" { cd `chart_dir` local actual=$(helm template \ @@ -390,6 +482,9 @@ load _helpers [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"overridden\"' ]] } +#-------------------------------------------------------------------- +# healthchecks + @test "meshGateway/Deployment: healthchecks are on by default" { cd `chart_dir` local actual=$(helm template \ @@ -423,6 +518,9 @@ load _helpers [ "${readiness}" = "false" ] } +#-------------------------------------------------------------------- +# hostPort + @test "meshGateway/Deployment: no hostPort by default" { cd `chart_dir` local actual=$(helm template \ @@ -450,6 +548,9 @@ load _helpers [ "${actual}" = "443" ] } +#-------------------------------------------------------------------- +# priorityClassName + @test "meshGateway/Deployment: no priorityClassName by default" { cd `chart_dir` local actual=$(helm template \ @@ -477,6 +578,9 @@ load _helpers [ "${actual}" = "name" ] } +#-------------------------------------------------------------------- +# nodeSelector + @test "meshGateway/Deployment: no nodeSelector by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/mesh-gateway-podsecuritypolicy.bats b/test/unit/mesh-gateway-podsecuritypolicy.bats index 4e0dfed40f..2fb55cf17c 100644 --- a/test/unit/mesh-gateway-podsecuritypolicy.bats +++ b/test/unit/mesh-gateway-podsecuritypolicy.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/PodSecurityPolicy: enabled with meshGateway.enabled and global.enablePodSecurityPolicies=true" { +@test "meshGateway/PodSecurityPolicy: enabled with meshGateway, connectInject and client.grpc enabled and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-podsecuritypolicy.yaml \ diff --git a/test/unit/mesh-gateway-service.bats b/test/unit/mesh-gateway-service.bats index 4264f0abca..ac8a7c3ed3 100755 --- a/test/unit/mesh-gateway-service.bats +++ b/test/unit/mesh-gateway-service.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/Service: disabled with meshGateway.enabled=true" { +@test "meshGateway/Service: disabled by default with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-service.yaml \ @@ -36,6 +36,9 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# annotations + @test "meshGateway/Service: no annotations by default" { cd `chart_dir` local actual=$(helm template \ @@ -63,6 +66,9 @@ load _helpers [ "${actual}" = "value" ] } +#-------------------------------------------------------------------- +# port + @test "meshGateway/Service: has default port" { cd `chart_dir` local actual=$(helm template \ @@ -90,6 +96,9 @@ load _helpers [ "${actual}" = "8443" ] } +#-------------------------------------------------------------------- +# targetPort + @test "meshGateway/Service: has default targetPort" { cd `chart_dir` local actual=$(helm template \ @@ -117,6 +126,9 @@ load _helpers [ "${actual}" = "8443" ] } +#-------------------------------------------------------------------- +# nodePort + @test "meshGateway/Service: no nodePort by default" { cd `chart_dir` local actual=$(helm template \ @@ -144,6 +156,9 @@ load _helpers [ "${actual}" = "8443" ] } +#-------------------------------------------------------------------- +# Service type + @test "meshGateway/Service: defaults to type ClusterIP" { cd `chart_dir` local actual=$(helm template \ @@ -171,6 +186,9 @@ load _helpers [ "${actual}" = "LoadBalancer" ] } +#-------------------------------------------------------------------- +# additionalSpec + @test "meshGateway/Service: can add additionalSpec" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/mesh-gateway-serviceaccount.bats b/test/unit/mesh-gateway-serviceaccount.bats index e6972222c5..5eaf64747a 100644 --- a/test/unit/mesh-gateway-serviceaccount.bats +++ b/test/unit/mesh-gateway-serviceaccount.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ServiceAccount: enabled with meshGateway.enabled = true" { +@test "meshGateway/ServiceAccount: enabled with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-serviceaccount.yaml \ diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index e95baa0836..388fa9e1b1 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -127,7 +127,7 @@ load _helpers [ "${actual}" = "remote" ] } -@test "server/ConfigMap: proxyDefaults should have no gateway mode if disabled" { +@test "server/ConfigMap: proxyDefaults should have no gateway mode if set to empty string" { cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ @@ -142,6 +142,21 @@ load _helpers [ "${actual}" = "null" ] } +@test "server/ConfigMap: proxyDefaults should have no gateway mode if set to null" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.globalMode=null' \ + --set 'client.grpc=true' \ + . | tee /dev/stderr | + yq -r '.data["proxy-defaults-config.json"]' | yq '.config_entries.bootstrap[0].mesh_gateway' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + @test "server/ConfigMap: global gateway mode is set even if there are no proxyDefaults" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index cadb75226b..92b49848ec 100644 --- a/values.yaml +++ b/values.yaml @@ -415,15 +415,15 @@ meshGateway: # If mesh gateways are enabled, a Deployment will be created that runs # gateways and Consul Connect will be configured to use gateways. # See https://www.consul.io/docs/connect/mesh_gateway.html - # Requirements: consul >= 1.6.0 and consul-k8s >= 0.8.2 if using global.bootstrapACLs. + # Requirements: consul >= 1.6.0 and consul-k8s >= 0.9.0 if using global.bootstrapACLs. enabled: false # Globally configure which mode the gateway should run in. - # Can be set to either "remote", "local", "none" or "". + # Can be set to either "remote", "local", "none" or empty string or null. # See https://consul.io/docs/connect/mesh_gateway.html#modes-of-operation for # a description of each mode. - # If set, connectInject.centralConfig.enabled should be set to true so that - # the global config will actually be used. + # If set to anything other than "" or null, connectInject.centralConfig.enabled + # should be set to true so that the global config will actually be used. # If set to the empty string, no global default will be set and the gateway mode # will need to be set individually for each service. globalMode: local @@ -501,6 +501,8 @@ meshGateway: # to expose the gateways directly from the node. # If hostNetwork is true, this must be null or set to the same port as # containerPort. + # NOTE: Cannot set to 8500 or 8502 because those are reserved for the Consul + # agent. hostPort: null # If there are no connect-enabled services running, then the gateway From 4930ebc72985808c8ca7f673f69d1b4e33834845 Mon Sep 17 00:00:00 2001 From: Analyser Date: Wed, 24 Jul 2019 18:43:50 +0800 Subject: [PATCH 211/739] Add annotations configuration to DNS Service. Many Cloud providers support bind Load Balancer address by using service annotations. Such as Amazon AWS, Alibaba AliCloud etc. So, then we can set a fixed LB IP address in coredns/kube-dns configMap settings, not a non-stable dynamic cluster IP. --- templates/dns-service.yaml | 4 ++++ test/unit/dns-service.bats | 24 ++++++++++++++++++++++++ values.yaml | 5 +++++ 3 files changed, 33 insertions(+) diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index cdedaf2a96..2d2ce8c231 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -10,6 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + {{- if .Values.dns.annotations }} + annotations: + {{ tpl .Values.dns.annotations . | nindent 4 | trim }} + {{- end }} spec: ports: - name: dns-tcp diff --git a/test/unit/dns-service.bats b/test/unit/dns-service.bats index 8acfdcfeb5..65fb34ee3c 100755 --- a/test/unit/dns-service.bats +++ b/test/unit/dns-service.bats @@ -41,3 +41,27 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "dns/Service: no annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'dns.enabled=true' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "dns/Service: can set annotations" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'dns.enabled=true' \ + --set 'dns.annotations=key: value' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} \ No newline at end of file diff --git a/values.yaml b/values.yaml index 92b49848ec..3bb42df107 100644 --- a/values.yaml +++ b/values.yaml @@ -254,6 +254,11 @@ client: dns: enabled: "-" + # Extra annotations to attach to the dns service + # This should be a multi-line string of + # annotations to apply to the dns Service + annotations: null + ui: # True if you want to enable the Consul UI. The UI will run only # on the server nodes. This makes UI access via the service below (if From 3daabf97fafada2e9caa118f5d9ae453c7a6724d Mon Sep 17 00:00:00 2001 From: FullGC Date: Wed, 1 May 2019 19:37:14 +0300 Subject: [PATCH 212/739] added default logLevel and consulWriteInterval --- templates/sync-catalog-deployment.yaml | 6 ++++++ values.yaml | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 37a376eca6..cb3d88aa46 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -79,6 +79,12 @@ spec: {{- if .Values.syncCatalog.nodePortSyncType }} -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} \ {{- end }} + {{- if .Values.syncCatalog.consulWriteInterval }} + -consul-write-interval={{ .Values.syncCatalog.consulWriteInterval }} \ + {{- end }} + {{- if .Values.syncCatalog.logLevel }} + -log-level={{ .Values.syncCatalog.logLevel }} \ + {{- end }} {{- if .Values.syncCatalog.k8sTag }} -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} \ {{- end }} diff --git a/values.yaml b/values.yaml index 3bb42df107..a1bf6af80e 100644 --- a/values.yaml +++ b/values.yaml @@ -344,6 +344,13 @@ syncCatalog: # beta.kubernetes.io/arch: amd64 nodeSelector: null + #Log verbosity level. Supported values (in order of detail) are \"trace\", "+ + #"\"debug\", \"info\", \"warn\", and \"error\".") + logLevel: info + + # The interval to perform syncing operations creating Consul services + consulWriteInterval: 30s + # ConnectInject will enable the automatic Connect sidecar injector. connectInject: enabled: false From 6bf79ab0047182a7cebe6bb33334e5d9505e7d6d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 14 Aug 2019 18:42:11 +0200 Subject: [PATCH 213/739] Update values.yaml --- values.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/values.yaml b/values.yaml index a1bf6af80e..9fabf946bb 100644 --- a/values.yaml +++ b/values.yaml @@ -344,12 +344,11 @@ syncCatalog: # beta.kubernetes.io/arch: amd64 nodeSelector: null - #Log verbosity level. Supported values (in order of detail) are \"trace\", "+ - #"\"debug\", \"info\", \"warn\", and \"error\".") + # Log verbosity level. One of "trace", "debug", "info", "warn", or "error". logLevel: info - # The interval to perform syncing operations creating Consul services - consulWriteInterval: 30s + # Override the default interval to perform syncing operations creating Consul services. + consulWriteInterval: null # ConnectInject will enable the automatic Connect sidecar injector. connectInject: From 0254fe32b98f2bcd61a2b63316e7998a09c9e1f4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 15 May 2019 09:55:48 -0400 Subject: [PATCH 214/739] Ability to specify DNS Service clusterIP. --- templates/dns-service.yaml | 3 +++ test/unit/dns-service.bats | 24 +++++++++++++++++++++++- values.yaml | 15 ++++++++++----- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index 2d2ce8c231..e7bca50735 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -15,6 +15,9 @@ metadata: {{ tpl .Values.dns.annotations . | nindent 4 | trim }} {{- end }} spec: +{{- if .Values.dns.clusterIP }} + clusterIP: {{ .Values.dns.clusterIP }} +{{- end }} ports: - name: dns-tcp port: 53 diff --git a/test/unit/dns-service.bats b/test/unit/dns-service.bats index 65fb34ee3c..787ba12c99 100755 --- a/test/unit/dns-service.bats +++ b/test/unit/dns-service.bats @@ -64,4 +64,26 @@ load _helpers . | tee /dev/stderr | yq -r '.metadata.annotations.key' | tee /dev/stderr) [ "${actual}" = "value" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# clusterIP + +@test "dns/Service: clusterIP not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + . | tee /dev/stderr | + yq '.spec | .clusterIP? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "dns/Service: specified clusterIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/dns-service.yaml \ + --set 'dns.clusterIP=192.168.1.1' \ + . | tee /dev/stderr | + yq '.spec | .clusterIP == "192.168.1.1"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 9fabf946bb..d4e73e094e 100644 --- a/values.yaml +++ b/values.yaml @@ -40,13 +40,13 @@ global: # Gossip encryption key. To enable gossip encryption, provide the name of # a Kubernetes secret that contains a gossip key. You can create a gossip - # key with the "consul keygen" command. - # See https://www.consul.io/docs/commands/keygen.html + # key with the "consul keygen" command. + # See https://www.consul.io/docs/commands/keygen.html gossipEncryption: secretName: null secretKey: null - # bootstrapACLs will automatically create and assign ACL tokens within + # bootstrapACLs will automatically create and assign ACL tokens within # the Consul cluster. This currently requires enabling both servers and # clients within Kubernetes. Additionally requires Consul v1.4+ and # consul-k8s v0.8.0+. @@ -151,7 +151,7 @@ server: annotations: null # extraEnvVars is a list of extra enviroment variables to set with the stateful set. These could be - # used to include proxy settings required for cloud auto-join feature, + # used to include proxy settings required for cloud auto-join feature, # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure # custom consul parameters. extraEnvironmentVars: {} @@ -216,7 +216,7 @@ client: annotations: null # extraEnvVars is a list of extra enviroment variables to set with the pod. These could be - # used to include proxy settings required for cloud auto-join feature, + # used to include proxy settings required for cloud auto-join feature, # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure # custom consul parameters. extraEnvironmentVars: {} @@ -253,6 +253,11 @@ client: # https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers dns: enabled: "-" + + # Set a predefined cluster IP for the DNS service. + # Useful if you need to reference the DNS service's IP + # address in CoreDNS config. + clusterIP: null # Extra annotations to attach to the dns service # This should be a multi-line string of From 515f286a5c1729078ab22274c5965df05dafb80f Mon Sep 17 00:00:00 2001 From: Justin Walz Date: Fri, 2 Aug 2019 16:02:52 -0700 Subject: [PATCH 215/739] Add support for k8s source namespace flag --- templates/sync-catalog-deployment.yaml | 3 +++ values.yaml | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index cb3d88aa46..e463b346d2 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -72,6 +72,9 @@ spec: {{- if .Values.syncCatalog.k8sPrefix }} -k8s-service-prefix="{{ .Values.syncCatalog.k8sPrefix}}" \ {{- end }} + {{- if .Values.syncCatalog.k8sSourceNamespace }} + -k8s-source-namespace="{{ .Values.syncCatalog.k8sSourceNamespace}}" \ + {{- end }} -k8s-write-namespace=${NAMESPACE} \ {{- if (not .Values.syncCatalog.syncClusterIPServices) }} -sync-clusterip-services=false \ diff --git a/values.yaml b/values.yaml index d4e73e094e..7e8f7b1708 100644 --- a/values.yaml +++ b/values.yaml @@ -311,6 +311,11 @@ syncCatalog: # prepended with "consul-". (Consul -> Kubernetes sync) k8sPrefix: null + # k8sSourceNamespace is the Kubernetes namespace to watch for service + # changes and sync to Consul. If this is not set then it will default + # to all namespaces. + k8sSourceNamespace: null + # consulPrefix is the service prefix which preprends itself # to Kubernetes services registered within Consul # For example, "k8s-" will register all services peprended with "k8s-". From 11b1a12a16715c62e43e7aa0d5af124ef2bacfd4 Mon Sep 17 00:00:00 2001 From: Lukas Schmitt Date: Thu, 8 Aug 2019 10:58:37 +0200 Subject: [PATCH 216/739] fix typo in connect-inject-clusterrole --- templates/connect-inject-clusterrole.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 036068b150..08f84d294b 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -20,7 +20,7 @@ rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] - resourcesName: + resourceNames: - {{ template "consul.fullname" . }}-connect-injector-webhook verbs: - use From 1a2172b5d4f589bd0bcc7bd43c67fcd72eff4493 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 6 Sep 2019 10:34:23 +0200 Subject: [PATCH 217/739] Wait for server pods to be running before acl init - The acl-init job can't succeed until servers are running and leaders are elected. Wait for servers to be running via an init container. - Don't run in a post-install hook so that helm install --wait won't fail. We had a race condition where helm install --wait won't run any post-install hooks until all resources become ready but our agent pods won't become ready until the acl-init job runs. So it just sits there and times out. --- templates/server-acl-init-job.yaml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index d1c261f308..e39fddc23a 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -11,10 +11,6 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} - annotations: - "helm.sh/hook": post-install - "helm.sh/hook-weight": "0" - "helm.sh/hook-delete-policy": hook-succeeded spec: template: metadata: @@ -29,6 +25,22 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init + initContainers: + - name: wait-for-leader + image: bitnami/kubectl:1.13 + command: + - "/bin/bash" + - "-c" + - | + echo "Waiting for {{ .Values.server.replicas }} server pods to be running" + COUNT=0; + while [[ $COUNT -lt {{ .Values.server.replicas }} ]]; do + sleep 5s; + COUNT=$(kubectl get pods -n {{ .Release.Namespace }} -l "app=consul,component=server,release={{.Release.Name}}" | grep 'Running' | wc -l); + echo "Current count: $COUNT"; + done; + # Sleep for 10 to allow for leader election. + sleep 10s; containers: - name: post-install-job image: {{ .Values.global.imageK8S }} From 76f00b4ffdcd66f92b7130c0b321883a5b6a7d52 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 6 Sep 2019 11:46:12 +0200 Subject: [PATCH 218/739] Release 0.9.0 --- CHANGELOG.md | 13 +++++++++++++ Chart.yaml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43c43cb67a..61ba143ee8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,21 @@ ## UNRELEASED +## 0.9.0 (Sep 6, 2019) + +IMPROVEMENTS: + + * Support running the consul snapshot agent + * Support mesh gateways + * Allow setting annotations for the DNS service + * Allow setting `-consul-write-interval`, `-log-level` and `-k8s-source-namespace` flags for consul-k8s sync + * Allow setting DNS service IP + * Fix issues where acl-init job would fail repeatedly and ACLs would not be + bootstrapped + BUG FIXES: * Fix enterprise license application when ACLs are turned off + * `rules` key must always be set (fixes https://github.com/hashicorp/consul-helm/issues/178) ## 0.8.1 (May 9, 2019) diff --git a/Chart.yaml b/Chart.yaml index a8d6f1fdf6..c96327a62f 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.9.0-beta +version: 0.9.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From b625bf57ef06c203fbafa8671b2393c1a5747c83 Mon Sep 17 00:00:00 2001 From: Michael George Attard Date: Thu, 28 Mar 2019 14:14:08 +0100 Subject: [PATCH 219/739] Remove random suffix from resource name --- templates/tests/test-runner.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 473b873823..835f34e610 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: "{{ template "consul.fullname" . }}-test-{{ randAlphaNum 5 | lower }}" + name: "{{ template "consul.fullname" . }}-test" labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} From 8cbc1596f909a447dcfa63d54bebd4e22a17bb95 Mon Sep 17 00:00:00 2001 From: Michael George Attard Date: Thu, 28 Mar 2019 14:31:30 +0100 Subject: [PATCH 220/739] Remove random value from resource --- templates/tests/test-runner.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 835f34e610..7538c82e14 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -22,7 +22,7 @@ spec: - "/bin/sh" - "-ec" - | - export VALUE="{{randAlphaNum 24 | lower }}" + export VALUE="{{ .Release.Name }}-$s78CUagt%Oq" export CONSUL_HTTP_ADDR="${HOST_IP}:8500" consul kv delete _consul_helm_test consul kv put _consul_helm_test $VALUE From 048722c33bb8ae3be3f196f98940a1b7561edc9e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Sep 2019 12:38:19 -0700 Subject: [PATCH 221/739] Update test-runner.yaml --- templates/tests/test-runner.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 7538c82e14..40bab50e27 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -22,7 +22,7 @@ spec: - "/bin/sh" - "-ec" - | - export VALUE="{{ .Release.Name }}-$s78CUagt%Oq" + export VALUE="{{ .Release.Name }}" export CONSUL_HTTP_ADDR="${HOST_IP}:8500" consul kv delete _consul_helm_test consul kv put _consul_helm_test $VALUE From 8b27cc138c14eeec734b57f9806d47ea39047422 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 19 Sep 2019 09:35:27 -0700 Subject: [PATCH 222/739] Latest version of Consul and consul-k8s --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 7e8f7b1708..e6001d81ff 100644 --- a/values.yaml +++ b/values.yaml @@ -16,7 +16,7 @@ global: # Examples: # image: "consul:1.5.0" # image: "hashicorp/consul-enterprise:1.5.0-ent" # Enterprise Consul image - image: "consul:1.5.0" + image: "consul:1.6.0" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden @@ -25,7 +25,7 @@ global: # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. - imageK8S: "hashicorp/consul-k8s:0.9.0" + imageK8S: "hashicorp/consul-k8s:0.9.1" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From ac210e339c4a4de34b07343db0690374b5d92440 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 19 Sep 2019 09:42:24 -0700 Subject: [PATCH 223/739] Update CHANGELOG and update Chart version --- CHANGELOG.md | 7 +++++++ Chart.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61ba143ee8..e69fca1b9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## UNRELEASED +## 0.10.0 (Sep 19, 2019) + +IMPROVEMENTS: + + * Use latest version of Consul (1.6.0) and consul-k8s (0.9.1) + * Remove random value from `helm test` to enable helmfile use [[GH-143](https://github.com/hashicorp/consul-helm/pull/143)] + ## 0.9.0 (Sep 6, 2019) IMPROVEMENTS: diff --git a/Chart.yaml b/Chart.yaml index c96327a62f..b15602cde1 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.9.0 +version: 0.10.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From f3ffaf7ec344830b0f56894941da6b2e93815e5a Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 3 Oct 2019 11:55:05 -0700 Subject: [PATCH 224/739] Update to latest consul-k8s version. This version fixes a bug that required Consul leaders to be elected prior to running the consul-k8s server-acl-init command. Since the command will now wait for leaders to be elected, we no longer need the init container. --- templates/server-acl-init-job.yaml | 16 ---------------- values.yaml | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index e39fddc23a..db7a1f5dff 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -25,22 +25,6 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init - initContainers: - - name: wait-for-leader - image: bitnami/kubectl:1.13 - command: - - "/bin/bash" - - "-c" - - | - echo "Waiting for {{ .Values.server.replicas }} server pods to be running" - COUNT=0; - while [[ $COUNT -lt {{ .Values.server.replicas }} ]]; do - sleep 5s; - COUNT=$(kubectl get pods -n {{ .Release.Namespace }} -l "app=consul,component=server,release={{.Release.Name}}" | grep 'Running' | wc -l); - echo "Current count: $COUNT"; - done; - # Sleep for 10 to allow for leader election. - sleep 10s; containers: - name: post-install-job image: {{ .Values.global.imageK8S }} diff --git a/values.yaml b/values.yaml index e6001d81ff..9faf60b18f 100644 --- a/values.yaml +++ b/values.yaml @@ -25,7 +25,7 @@ global: # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. - imageK8S: "hashicorp/consul-k8s:0.9.1" + imageK8S: "hashicorp/consul-k8s:0.9.2" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 24d3115a2f04e8b5058f43b1d67afe6eff20df19 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 4 Oct 2019 16:26:17 -0700 Subject: [PATCH 225/739] Update CHANGELOG --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69fca1b9d..0e29956688 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,16 @@ ## UNRELEASED -## 0.10.0 (Sep 19, 2019) +## 0.10.0 (Oct 4, 2019) IMPROVEMENTS: - * Use latest version of Consul (1.6.0) and consul-k8s (0.9.1) + * Use latest version of Consul (1.6.0) and consul-k8s (0.9.2) * Remove random value from `helm test` to enable helmfile use [[GH-143](https://github.com/hashicorp/consul-helm/pull/143)] + +BUG FIXES: + + * The latest version of `consul-k8s` fixes issues with the `server-acl-init` + job failing repeatedly. ## 0.9.0 (Sep 6, 2019) From a6adfe54b3715b9ef9bfa2affe3a1660ab6eddb2 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 9 Oct 2019 16:21:12 -0700 Subject: [PATCH 226/739] Add server-acl-init-cleanup job This job deletes the server-acl-init job when it completes successfully. This keeps things clean and more importantly fixes the issue where if you try to make a change to the helm values that result in updating the spec for the Job that you get an error because the Job spec is immutable. If the Job is deleted then this isn't a problem. Also upgrades consul-k8s to the version with the new delete-completed-job command. --- .../server-acl-init-cleanup-clusterrole.yaml | 19 +++++++ ...r-acl-init-cleanup-clusterrolebinding.yaml | 23 ++++++++ templates/server-acl-init-cleanup-job.yaml | 55 +++++++++++++++++++ ...erver-acl-init-cleanup-serviceaccount.yaml | 16 ++++++ templates/server-acl-init-clusterrole.yaml | 7 ++- .../server-acl-init-cleanup-clusterrole.bats | 44 +++++++++++++++ ...r-acl-init-cleanup-clusterrolebinding.bats | 44 +++++++++++++++ test/unit/server-acl-init-cleanup-job.bats | 54 ++++++++++++++++++ ...erver-acl-init-cleanup-serviceaccount.bats | 44 +++++++++++++++ values.yaml | 2 +- 10 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 templates/server-acl-init-cleanup-clusterrole.yaml create mode 100644 templates/server-acl-init-cleanup-clusterrolebinding.yaml create mode 100644 templates/server-acl-init-cleanup-job.yaml create mode 100644 templates/server-acl-init-cleanup-serviceaccount.yaml create mode 100644 test/unit/server-acl-init-cleanup-clusterrole.bats create mode 100644 test/unit/server-acl-init-cleanup-clusterrolebinding.bats create mode 100644 test/unit/server-acl-init-cleanup-job.bats create mode 100644 test/unit/server-acl-init-cleanup-serviceaccount.bats diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml new file mode 100644 index 0000000000..8e5cbfbb1a --- /dev/null +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "delete"] +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml new file mode 100644 index 0000000000..c73e813fd5 --- /dev/null +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -0,0 +1,23 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml new file mode 100644 index 0000000000..ed387909b6 --- /dev/null +++ b/templates/server-acl-init-cleanup-job.yaml @@ -0,0 +1,55 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +# This job deletes the server-acl-init job once it completes successfully. +# It runs as a helm hook because it only needs to run when the server-acl-init +# Job gets recreated which only happens during an install or upgrade. +# We also utilize the helm hook-delete-policy to delete this job itself. +# We want to delete the server-acl-init job because once it runs successfully +# it's not needed and also because if it stays around then when users run +# helm upgrade with values that change the spec of the job, Kubernetes errors +# because the job spec is immutable. If the job is deleted, then a new job +# is created and there's no error. +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "0" + # If the hook fails then all that happens is we didn't delete the job. + # There's no reason for *this* job to stay around in that case so delete + # regardless of success. + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init-cleanup + containers: + - name: server-acl-init-cleanup + image: {{ .Values.global.imageK8S }} + command: + - consul-k8s + args: + - delete-completed-job + - -k8s-namespace={{ .Release.Namespace }} + - {{ template "consul.fullname" . }}-server-acl-init + {{- end }} + {{- end }} + {{- end }} diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml new file mode 100644 index 0000000000..c008bb5b9e --- /dev/null +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index b5c901e8e1..9d0ad3740a 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -22,6 +22,11 @@ rules: verbs: - create - get + - apiGroups: ["apps"] + resources: + - statefulsets + verbs: + - get {{- if .Values.connectInject.enabled }} - apiGroups: [""] resources: @@ -36,4 +41,4 @@ rules: {{- end }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats new file mode 100644 index 0000000000..3f5dd483fc --- /dev/null +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInitCleanup/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ClusterRole: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ClusterRole: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ClusterRole: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats new file mode 100644 index 0000000000..34e0e0ea4c --- /dev/null +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInitCleanup/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ClusterRoleBinding: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ClusterRoleBinding: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ClusterRoleBinding: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats new file mode 100644 index 0000000000..4e4bd8c8ec --- /dev/null +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -0,0 +1,54 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInitCleanup/Job: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/Job: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/Job: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/Job: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/Job: consul-k8s delete-completed-job is called with correct arguments" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -c '.spec.template.spec.containers[0].args' | tee /dev/stderr) + [ "${actual}" = '["delete-completed-job","-k8s-namespace=default","release-name-consul-server-acl-init"]' ] +} diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats new file mode 100644 index 0000000000..b4cb73919a --- /dev/null +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInitCleanup/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ServiceAccount: enabled with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ServiceAccount: disabled with server=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/ServiceAccount: disabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 9faf60b18f..1d7c4b12d5 100644 --- a/values.yaml +++ b/values.yaml @@ -25,7 +25,7 @@ global: # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. - imageK8S: "hashicorp/consul-k8s:0.9.2" + imageK8S: "hashicorp/consul-k8s:0.9.3" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From 06b0ca01c48cd7bd07f527a47b7d0bbb72d9b765 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 9 May 2019 14:48:22 -0400 Subject: [PATCH 227/739] Ability to specify Consul client daemonset affinity. --- templates/client-daemonset.yaml | 4 ++++ test/unit/client-daemonset.bats | 22 ++++++++++++++++++++++ values.yaml | 12 ++++++++++++ 3 files changed, 38 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 52828257ac..a308f01956 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -32,6 +32,10 @@ spec: {{- tpl .Values.client.annotations . | nindent 8 }} {{- end }} spec: + {{- if .Values.client.affinity }} + affinity: + {{ tpl .Values.client.affinity . | nindent 8 | trim }} + {{- end }} {{- if .Values.client.tolerations }} tolerations: {{ tpl .Values.client.tolerations . | nindent 8 | trim }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index a77695ec07..4501896f33 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -243,6 +243,28 @@ load _helpers [ "${actual}" = "testing" ] } +#-------------------------------------------------------------------- +# affinity + +@test "client/DaemonSet: affinity not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec | .affinity? == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: specified affinity" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.affinity=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .affinity == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # priorityClassName diff --git a/values.yaml b/values.yaml index 9faf60b18f..06d13ae3c9 100644 --- a/values.yaml +++ b/values.yaml @@ -206,6 +206,18 @@ client: # beta.kubernetes.io/arch: amd64 nodeSelector: null + # Affinity Settings for Client pods + # ref https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # Example: + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: node-role.kubernetes.io/master + # operator: DoesNotExist + affinity: {} + # used to assign priority to client pods # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" From dfb4a0bdaa9cd6e2f40c7bd7a6cc34cc6edf47dd Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 15 Oct 2019 12:16:22 -0700 Subject: [PATCH 228/739] Update values.yaml --- values.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/values.yaml b/values.yaml index 06d13ae3c9..d25f74f5e3 100644 --- a/values.yaml +++ b/values.yaml @@ -206,10 +206,10 @@ client: # beta.kubernetes.io/arch: amd64 nodeSelector: null - # Affinity Settings for Client pods - # ref https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # Affinity Settings for Client pods, formatted as a multi-line YAML string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity # Example: - # affinity: + # affinity: | # nodeAffinity: # requiredDuringSchedulingIgnoredDuringExecution: # nodeSelectorTerms: From 3c33bd41b225e91c172399f0a2b4b5a06e7516d6 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 15 Oct 2019 17:03:07 -0700 Subject: [PATCH 229/739] Use the latest Consul version (1.6.1) --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index ed6153ecfa..e06df8ac2a 100644 --- a/values.yaml +++ b/values.yaml @@ -16,7 +16,7 @@ global: # Examples: # image: "consul:1.5.0" # image: "hashicorp/consul-enterprise:1.5.0-ent" # Enterprise Consul image - image: "consul:1.6.0" + image: "consul:1.6.1" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden From 4d68ce4f8ea16776b4b31e1b8718db983101c7be Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 15 Oct 2019 17:17:25 -0700 Subject: [PATCH 230/739] Update CHANGELOG and Helm chart version --- CHANGELOG.md | 14 ++++++++++++++ Chart.yaml | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e29956688..5afc0b0d08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ ## UNRELEASED +## 0.11.0 (Oct 15, 2019) + +IMPROVEMENTS: + + * Use the latest version of Consul (1.6.1) + +BUG FIXES: + + * Use the latest version of `consul-k8s` (0.9.3) which fixes issues with upgrading between Helm chart + versions when `bootstrapACLs` is enabled [[GH-246](https://github.com/hashicorp/consul-helm/pull/246)]. + * Add `server-acl-init-cleanup` job to clean up the `server-acl-init` job + when it completes successfully [[GH-246](https://github.com/hashicorp/consul-helm/pull/246)]. + * Add the ability to specify Consul client daemonset affinity [[GH-165](https://github.com/hashicorp/consul-helm/pull/165)] + ## 0.10.0 (Oct 4, 2019) IMPROVEMENTS: diff --git a/Chart.yaml b/Chart.yaml index b15602cde1..85d238a9d5 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.10.0 +version: 0.11.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From f68a82afb93e07b9a68304048075b702819f026a Mon Sep 17 00:00:00 2001 From: Brian Surber Date: Fri, 7 Jun 2019 14:31:43 -0700 Subject: [PATCH 231/739] Enable server acl initialization if servers & bootstrapACLs are enabled, regardless of client --- templates/server-acl-init-clusterrole.yaml | 2 - .../server-acl-init-clusterrolebinding.yaml | 2 - templates/server-acl-init-job.yaml | 5 +- templates/server-acl-init-serviceaccount.yaml | 2 - test/unit/server-acl-init-clusterrole.bats | 16 +++++- .../server-acl-init-clusterrolebinding.bats | 16 +++++- test/unit/server-acl-init-job.bats | 50 +++++++++++++------ test/unit/server-acl-init-serviceaccount.bats | 14 +++++- 8 files changed, 79 insertions(+), 28 deletions(-) diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 9d0ad3740a..627a2f8592 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -41,4 +40,3 @@ rules: {{- end }} {{- end }} {{- end }} -{{- end }} diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index 017b7097e9..620a01ae59 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -20,4 +19,3 @@ subjects: namespace: {{ .Release.Namespace }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index db7a1f5dff..996bcdb03e 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: batch/v1 kind: Job @@ -61,7 +60,9 @@ spec: {{- if .Values.client.snapshotAgent.enabled }} -create-snapshot-agent-token=true \ {{- end }} + {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} + -create-client-token=false \ + {{- end }} -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} -{{- end }} diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index f254a3c429..7c0564367c 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: v1 kind: ServiceAccount @@ -13,4 +12,3 @@ metadata: release: {{ .Release.Name }} {{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index f3dc033dfb..9eceba9326 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -32,13 +32,25 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRole: enabled with server=true, client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRole: enabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index 29fd35501c..b917a1e93f 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -32,13 +32,25 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRoleBinding: enabled with server=true, client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrolebinding.yaml \ --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRoleBinding: enabled with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 9b6209d2a4..c4e2dc896e 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -11,36 +11,56 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/Job: enabled with global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled server & client acls with global.bootstrapACLs=true" { cd `chart_dir` - local actual=$(helm template \ + local actual="$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + . | tee /dev/stderr)" + local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) + local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) + [ "${actual_enabled}" = "true" ] + [ "${actual_client_acl_disabled}" = "false" ] } -@test "serverACLInit/Job: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: disabled server & client acls with server=false and global.bootstrapACLs=true" { cd `chart_dir` - local actual=$(helm template \ + local actual="$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ --set 'server.enabled=false' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + . | tee /dev/stderr)" + local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) + local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) + [ "${actual_enabled}" = "false" ] + [ "${actual_client_acl_disabled}" = "false" ] } -@test "serverACLInit/Job: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled server acls, disabled client acls with server=true, client=false and global.bootstrapACLs=true" { cd `chart_dir` - local actual=$(helm template \ + local actual="$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=true' \ --set 'client.enabled=false' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + . | tee /dev/stderr)" + local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) + local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) + [ "${actual_enabled}" = "true" ] + [ "${actual_client_acl_disabled}" = "true" ] +} + +@test "serverACLInit/Job: enabled server acls, disabled client acls with client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual="$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr)" + local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) + local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) + [ "${actual_enabled}" = "true" ] + [ "${actual_client_acl_disabled}" = "true" ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index a9f4e6b645..cc5a125eb9 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -32,6 +32,18 @@ load _helpers [ "${actual}" = "false" ] } +@test "serverACLInit/ServiceAccount: enabled with server=true, client=false and global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=true' \ + --set 'client.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + @test "serverACLInit/ServiceAccount: disabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ @@ -40,5 +52,5 @@ load _helpers --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } From ab3e8c53bbd9a7afe8be2c3ebf86f28202e841e4 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 15 Oct 2019 13:56:25 -0700 Subject: [PATCH 232/739] Updates for server-acl-init with clients disabled - enable the cleanup job when clients are disabled - refactor tests --- .../server-acl-init-cleanup-clusterrole.yaml | 2 - ...r-acl-init-cleanup-clusterrolebinding.yaml | 2 - templates/server-acl-init-cleanup-job.yaml | 2 - ...erver-acl-init-cleanup-serviceaccount.yaml | 2 - .../server-acl-init-cleanup-clusterrole.bats | 6 +- ...r-acl-init-cleanup-clusterrolebinding.bats | 4 +- test/unit/server-acl-init-cleanup-job.bats | 4 +- ...erver-acl-init-cleanup-serviceaccount.bats | 4 +- test/unit/server-acl-init-clusterrole.bats | 12 ---- .../server-acl-init-clusterrolebinding.bats | 12 ---- test/unit/server-acl-init-job.bats | 61 ++++++++++--------- test/unit/server-acl-init-serviceaccount.bats | 14 +---- 12 files changed, 42 insertions(+), 83 deletions(-) diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index 8e5cbfbb1a..20509ac694 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -16,4 +15,3 @@ rules: verbs: ["get", "delete"] {{- end }} {{- end }} -{{- end }} diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml index c73e813fd5..789b5526a2 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -20,4 +19,3 @@ subjects: namespace: {{ .Release.Namespace }} {{- end }} {{- end }} -{{- end }} diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index ed387909b6..9ad32e92d3 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} # This job deletes the server-acl-init job once it completes successfully. # It runs as a helm hook because it only needs to run when the server-acl-init @@ -52,4 +51,3 @@ spec: - {{ template "consul.fullname" . }}-server-acl-init {{- end }} {{- end }} - {{- end }} diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index c008bb5b9e..79b1d5c661 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -1,5 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} apiVersion: v1 kind: ServiceAccount @@ -13,4 +12,3 @@ metadata: release: {{ .Release.Name }} {{- end }} {{- end }} -{{- end }} diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index 3f5dd483fc..f6852515de 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -32,13 +32,13 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRole: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRole: enabled with client=true and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrole.yaml \ --set 'global.bootstrapACLs=true' \ - --set 'client.enabled=false' \ + --set 'client.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats index 34e0e0ea4c..2f16966253 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -32,7 +32,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRoleBinding: enabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ @@ -40,5 +40,5 @@ load _helpers --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index 4e4bd8c8ec..42f2628a3a 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -32,7 +32,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/Job: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/Job: enabled with client=true and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ @@ -40,7 +40,7 @@ load _helpers --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } @test "serverACLInitCleanup/Job: consul-k8s delete-completed-job is called with correct arguments" { diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index b4cb73919a..0c1d1d9d93 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -32,7 +32,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ServiceAccount: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ServiceAccount: enabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-serviceaccount.yaml \ @@ -40,5 +40,5 @@ load _helpers --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index 9eceba9326..e005af6469 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -32,18 +32,6 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: enabled with server=true, client=false and global.bootstrapACLs=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'server.enabled=true' \ - --set 'client.enabled=false' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - @test "serverACLInit/ClusterRole: enabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index b917a1e93f..8ccdc229a8 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -32,18 +32,6 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with server=true, client=false and global.bootstrapACLs=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'server.enabled=true' \ - --set 'client.enabled=false' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - @test "serverACLInit/ClusterRoleBinding: enabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index c4e2dc896e..1f674d1c2c 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -11,56 +11,59 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/Job: enabled server & client acls with global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled with global.bootstrapACLs=true" { cd `chart_dir` - local actual="$(helm template \ + local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr)" - local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) - local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) - [ "${actual_enabled}" = "true" ] - [ "${actual_client_acl_disabled}" = "false" ] + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "serverACLInit/Job: disabled server & client acls with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: disabled with server=false and global.bootstrapACLs=true" { cd `chart_dir` - local actual="$(helm template \ + local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ --set 'server.enabled=false' \ - . | tee /dev/stderr)" - local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) - local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) - [ "${actual_enabled}" = "false" ] - [ "${actual_client_acl_disabled}" = "false" ] + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } -@test "serverACLInit/Job: enabled server acls, disabled client acls with server=true, client=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled with client=false global.bootstrapACLs=true" { cd `chart_dir` - local actual="$(helm template \ + local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ - --set 'server.enabled=true' \ --set 'client.enabled=false' \ - . | tee /dev/stderr)" - local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) - local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) - [ "${actual_enabled}" = "true" ] - [ "${actual_client_acl_disabled}" = "true" ] + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "serverACLInit/Job: enabled server acls, disabled client acls with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { cd `chart_dir` - local actual="$(helm template \ + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2] | contains("-create-client-token=false")' | + tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: sets -create-client-token=false when client is disabled" { + cd `chart_dir` + local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' \ --set 'client.enabled=false' \ - . | tee /dev/stderr)" - local actual_enabled=$(echo "$actual" | yq 'length > 0' | tee /dev/stderr) - local actual_client_acl_disabled=$(echo "$actual" | grep "create-client-token=false" >/dev/null && echo "true" || echo "false" | tee /dev/stderr ) - [ "${actual_enabled}" = "true" ] - [ "${actual_client_acl_disabled}" = "true" ] + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2] | contains("-create-client-token=false")' | + tee /dev/stderr) + [ "${actual}" = "true" ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index cc5a125eb9..758e0a32a3 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -32,19 +32,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ServiceAccount: enabled with server=true, client=false and global.bootstrapACLs=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-acl-init-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'server.enabled=true' \ - --set 'client.enabled=false' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "serverACLInit/ServiceAccount: disabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ServiceAccount: enabled with client=false and global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-serviceaccount.yaml \ From 3835b2298d5c2413c43e788091da67418b2bcd3e Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 17 Oct 2019 10:17:48 -0700 Subject: [PATCH 233/739] Add CircleCI config (#254) * Upgrade to terraform 0.12 * Add terraform to the Test.dockerfile * Add CircleCI config * Rename .circleci/config.yaml to .circleci/config.yml * Use env variable for the terraform version * Switch to hashicorpdev/consul-helm-test Docker image * Specify directory for terraform commands Also, add a clarifying comment describing which image is being used * Update .circleci/config.yml Co-Authored-By: Luke Kysow <1034429+lkysow@users.noreply.github.com> * Only run acceptance tests on the changes to master Plus, minor changes to terraform commands. * Split out acceptance tests into multiple steps for clarity * use multiple steps rather than a single step * 'terraform destroy' step runs always, even if previous steps fail * decrease GKE cluster node pool from 5 to 3 to make spin ups faster * wait for Helm to initialize to make sure tiller is ready * use the latest consul-helm-test docker image --- .circleci/config.yml | 51 +++++++++++++++++++++++++++++++++++++ test/docker/Test.dockerfile | 8 +++++- test/terraform/main.tf | 28 ++++++++++---------- test/terraform/outputs.tf | 4 +-- 4 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..e32fcfd182 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,51 @@ +version: 2 +jobs: + unit: + docker: + # This image is built from test/docker/Test.dockerfile + - image: hashicorpdev/consul-helm-test:0.3.0 + + steps: + - checkout + + - run: + name: Run Unit Tests + command: bats ./test/unit + + acceptance: + docker: + # This image is build from test/docker/Test.dockerfile + - image: hashicorpdev/consul-helm-test:0.3.0 + + steps: + - checkout + + - run: + name: terraform init & apply + command: | + terraform init test/terraform + echo "${GOOGLE_CREDENTIALS}" | gcloud auth activate-service-account --key-file=- + + terraform apply -var project=${CLOUDSDK_CORE_PROJECT} -var init_cli=true -auto-approve test/terraform + + - run: + name: Run acceptance tests + command: bats ./test/acceptance + + - run: + name: terraform destroy + command: | + terraform destroy -auto-approve + when: always + +workflows: + version: 2 + test: + jobs: + - unit + - acceptance: + requires: + - unit + filters: + branches: + only: master diff --git a/test/docker/Test.dockerfile b/test/docker/Test.dockerfile index 51cc166e89..7e3ec3b716 100644 --- a/test/docker/Test.dockerfile +++ b/test/docker/Test.dockerfile @@ -10,6 +10,7 @@ FROM alpine:latest WORKDIR /root ENV BATS_VERSION "1.1.0" +ENV TERRAFORM_VERSION "0.12.10" # base packages RUN apk update && apk add --no-cache --virtual .build-deps \ @@ -31,6 +32,11 @@ RUN curl -OL https://dl.google.com/dl/cloudsdk/channels/rapid/install_google_clo bash install_google_cloud_sdk.bash --disable-prompts --install-dir='/root/' && \ ln -s /root/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud +# terraform +RUN curl -sSL https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -o /tmp/tf.zip \ + && unzip /tmp/tf.zip \ + && ln -s /root/terraform /usr/local/bin/terraform + # kubectl RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ chmod +x ./kubectl && \ @@ -42,4 +48,4 @@ RUN curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | # bats RUN curl -sSL https://github.com/bats-core/bats-core/archive/v${BATS_VERSION}.tar.gz -o /tmp/bats.tgz \ && tar -zxf /tmp/bats.tgz -C /tmp \ - && /bin/bash /tmp/bats-core-$BATS_VERSION/install.sh /usr/local + && /bin/bash /tmp/bats-core-${BATS_VERSION}/install.sh /usr/local diff --git a/test/terraform/main.tf b/test/terraform/main.tf index a73df6a717..68fd74fd8e 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -3,7 +3,7 @@ locals { } provider "google" { - project = "${var.project}" + project = var.project } resource "random_id" "suffix" { @@ -11,24 +11,24 @@ resource "random_id" "suffix" { } data "google_container_engine_versions" "main" { - zone = "${var.zone}" + location = var.zone } resource "google_container_cluster" "cluster" { name = "consul-k8s-${random_id.suffix.dec}" - project = "${var.project}" + project = var.project enable_legacy_abac = true - initial_node_count = 5 - zone = "${var.zone}" - min_master_version = "${data.google_container_engine_versions.main.latest_master_version}" - node_version = "${data.google_container_engine_versions.main.latest_node_version}" + initial_node_count = 3 + location = var.zone + min_master_version = data.google_container_engine_versions.main.latest_master_version + node_version = data.google_container_engine_versions.main.latest_node_version } resource "null_resource" "kubectl" { - count = "${var.init_cli ? 1 : 0 }" + count = var.init_cli ? 1 : 0 - triggers { - cluster = "${google_container_cluster.cluster.id}" + triggers = { + cluster = google_container_cluster.cluster.id } # On creation, we want to setup the kubectl credentials. The easiest way @@ -55,17 +55,17 @@ resource "null_resource" "kubectl" { } resource "null_resource" "helm" { - count = "${var.init_cli ? 1 : 0 }" + count = var.init_cli ? 1 : 0 depends_on = ["null_resource.kubectl"] - triggers { - cluster = "${google_container_cluster.cluster.id}" + triggers = { + cluster = google_container_cluster.cluster.id } provisioner "local-exec" { command = < Date: Tue, 15 Oct 2019 11:10:26 -0700 Subject: [PATCH 234/739] Fix docs copy-paste mistake --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index e06df8ac2a..4451013b3b 100644 --- a/values.yaml +++ b/values.yaml @@ -178,7 +178,7 @@ client: resources: null # extraConfig is a raw string of extra configuration to set with the - # server. This should be JSON. + # client. This should be JSON. extraConfig: | {} From 3b9b29fa9f6538ada3d54e7696b44607e7dbf7e9 Mon Sep 17 00:00:00 2001 From: Anton Fayzrahmanov Date: Wed, 4 Sep 2019 14:05:31 +0300 Subject: [PATCH 235/739] Less privileges when syncCatalog.toK8S = false --- templates/sync-catalog-clusterrole.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/sync-catalog-clusterrole.yaml b/templates/sync-catalog-clusterrole.yaml index 90bc051abb..9366c04b5e 100644 --- a/templates/sync-catalog-clusterrole.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -18,10 +18,12 @@ rules: - get - list - watch +{{- if .Values.syncCatalog.toK8S }} - update - patch - delete - create +{{- end }} - apiGroups: [""] resources: - nodes From 94bb29b1bfdb474b05b9eb347021f93f0b6c307f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 15 Oct 2019 11:34:43 -0700 Subject: [PATCH 236/739] Add tests for reduced privileges when toK8S=false --- test/unit/sync-catalog-clusterrole.bats | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/unit/sync-catalog-clusterrole.bats b/test/unit/sync-catalog-clusterrole.bats index 85e79cf508..61932f3641 100755 --- a/test/unit/sync-catalog-clusterrole.bats +++ b/test/unit/sync-catalog-clusterrole.bats @@ -79,3 +79,28 @@ load _helpers yq -r '.rules[2].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] } + +#-------------------------------------------------------------------- +# syncCatalog.toK8S={true,false} + +@test "syncCatalog/ClusterRole: has reduced permissions if toK8s=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-clusterrole.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toK8S=false' \ + . | tee /dev/stderr | + yq -c '.rules[0].verbs' | tee /dev/stderr) + [ "${actual}" = '["get","list","watch"]' ] +} + +@test "syncCatalog/ClusterRole: has full permissions if toK8s=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-clusterrole.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toK8S=true' \ + . | tee /dev/stderr | + yq -c '.rules[0].verbs' | tee /dev/stderr) + [ "${actual}" = '["get","list","watch","update","patch","delete","create"]' ] +} From 02533bf4bbbb0bab282a5aa9bcb7d4464683f727 Mon Sep 17 00:00:00 2001 From: Michael George Attard Date: Thu, 28 Mar 2019 14:51:29 +0100 Subject: [PATCH 237/739] Tests are now optional --- templates/tests/test-runner.yaml | 2 ++ values.yaml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 40bab50e27..637bcb42e1 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -1,3 +1,4 @@ +{{- if (.Values.tests.enabled) }} apiVersion: v1 kind: Pod metadata: @@ -29,3 +30,4 @@ spec: [ `consul kv get _consul_helm_test` = "$VALUE" ] consul kv delete _consul_helm_test restartPolicy: Never +{{- end }} diff --git a/values.yaml b/values.yaml index e06df8ac2a..f08310230d 100644 --- a/values.yaml +++ b/values.yaml @@ -575,3 +575,6 @@ meshGateway: # Optional YAML string for additional annotations. annotations: null + +tests: + enabled: true From edaa0803dba2e54e566ebcd44272eaf9e530e367 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 15 Oct 2019 11:51:01 -0700 Subject: [PATCH 238/739] Add docs to tests.enabled value --- templates/tests/test-runner.yaml | 2 +- values.yaml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 637bcb42e1..2ea4d795d6 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -1,4 +1,4 @@ -{{- if (.Values.tests.enabled) }} +{{- if .Values.tests.enabled }} apiVersion: v1 kind: Pod metadata: diff --git a/values.yaml b/values.yaml index f08310230d..50218dfd04 100644 --- a/values.yaml +++ b/values.yaml @@ -576,5 +576,8 @@ meshGateway: # Optional YAML string for additional annotations. annotations: null +# Control whether a test Pod manifest is generated when running helm template. +# When using helm install, the test Pod is not submitted to the cluster so this +# is only useful when running helm template. tests: enabled: true From 9297790ae637358dfc4b09935554abd750d86829 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 17 Oct 2019 14:06:51 -0700 Subject: [PATCH 239/739] Test tests.enabled setting --- test/unit/test-runner.bats | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/unit/test-runner.bats diff --git a/test/unit/test-runner.bats b/test/unit/test-runner.bats new file mode 100644 index 0000000000..2b1fba6872 --- /dev/null +++ b/test/unit/test-runner.bats @@ -0,0 +1,22 @@ +#!/usr/bin/env bats + +load _helpers + +@test "testRunner/Pod: enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "testRunner/Pod: disabled when tests.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'tests.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} From bb9cea502011feb611f1b3c9ffd1c1df55f52b16 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 17 Oct 2019 14:12:22 -0700 Subject: [PATCH 240/739] Run `helm test` in acceptance tests --- test/acceptance/server.bats | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/acceptance/server.bats b/test/acceptance/server.bats index 0c81cd1568..371756dc12 100644 --- a/test/acceptance/server.bats +++ b/test/acceptance/server.bats @@ -12,6 +12,8 @@ load _helpers wc -l) [ "${server_count}" -eq "3" ] + helm test consul + # Clean up helm_delete } From 1b644036f85bc31a1eea6964cc1619315a769204 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 17 Oct 2019 16:57:17 -0700 Subject: [PATCH 241/739] Ensure caBundle is set to string Without this change, we output: caBundle: when .Values.connectInject.certs.caBundle is empty instead of caBundle: "" I can't reproduce the issue (#213) however I'm guessing this may be the cause if Kubernetes is treating this as null instead of the empty string. --- templates/connect-inject-mutatingwebhook.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 4138895c51..2ca5762456 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -17,7 +17,7 @@ webhooks: name: {{ template "consul.fullname" . }}-connect-injector-svc namespace: {{ .Release.Namespace }} path: "/mutate" - caBundle: {{ .Values.connectInject.certs.caBundle }} + caBundle: {{ .Values.connectInject.certs.caBundle | quote }} rules: - operations: [ "CREATE" ] apiGroups: [""] From 839babe2029b31303bf0a0aa924e7a39d7f869dd Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 18 Oct 2019 12:54:18 -0700 Subject: [PATCH 242/739] Document aclBindingRuleSelector --- values.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/values.yaml b/values.yaml index 4f9e4fbdd2..121f00bd5f 100644 --- a/values.yaml +++ b/values.yaml @@ -420,10 +420,16 @@ connectInject: # beta.kubernetes.io/arch: amd64 nodeSelector: null - # aclBindingRuleSelector is a string that defines the automatic binding - # rule to control the allowed authentication for Connect injection. The - # default disallows using the default service account for ACl generation. - # Requires Consul v1.5+ and consul-k8s v0.8.0+. + # aclBindingRuleSelector accepts a query that defines which Service Accounts + # can authenticate to Consul and receive an ACL token during Connect injection. + # The default setting, i.e. serviceaccount.name!=default, prevents the + # 'default' Service Account from logging in. + # If set to an empty string all service accounts can log in. + # This only has effect if ACLs are enabled. + # + # See https://www.consul.io/docs/acl/acl-auth-methods.html#binding-rules + # and https://www.consul.io/docs/acl/auth-methods/kubernetes.html#trusted-identity-attributes + # for more details. aclBindingRuleSelector: "serviceaccount.name!=default" # Requires Consul v1.5+ and consul-k8s v0.8.1+ From 0f949437195597cd8bcdd9a93f4f4e5e49f0418e Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Wed, 23 Oct 2019 14:55:53 +1000 Subject: [PATCH 243/739] Convert json.Numbers to string then to int so that comparisons happen as expected. --- templates/_helpers.tpl | 6 +++--- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 6 +++--- test/unit/client-daemonset.bats | 15 +++++++++++++++ test/unit/server-statefulset.bats | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 7333b4ab01..176b74d404 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -35,15 +35,15 @@ use the integer value Add a special case for replicas=1, where it should default to 0 as well. */}} {{- define "consul.pdb.maxUnavailable" -}} -{{- if eq (int .Values.server.replicas) 1 -}} +{{- if eq (int (toString .Values.server.replicas)) 1 -}} {{ 0 }} {{- else if .Values.server.disruptionBudget.maxUnavailable -}} {{ .Values.server.disruptionBudget.maxUnavailable -}} {{- else -}} -{{- if eq (int .Values.server.replicas) 3 -}} +{{- if eq (int (toString .Values.server.replicas)) 3 -}} {{- 1 -}} {{- else -}} -{{- sub (div (int .Values.server.replicas) 2) 1 -}} +{{- sub (div (int (toString .Values.server.replicas)) 2) 1 -}} {{- end -}} {{- end -}} {{- end -}} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index a308f01956..07281d76bf 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -128,7 +128,7 @@ spec: {{- end }} {{- else }} {{- if .Values.server.enabled }} - {{- range $index := until (.Values.server.replicas | int) }} + {{- range $index := until (toString (.Values.server.replicas) | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 6552fea8b7..d0b52cc4f1 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -14,7 +14,7 @@ spec: serviceName: {{ template "consul.fullname" . }}-server podManagementPolicy: Parallel replicas: {{ .Values.server.replicas }} - {{- if (gt (int .Values.server.updatePartition) 0) }} + {{- if (gt (int (toString .Values.server.updatePartition)) 0) }} updateStrategy: type: RollingUpdate rollingUpdate: @@ -118,7 +118,7 @@ spec: {{- if .Values.ui.enabled }} -ui \ {{- end }} - {{- range $index := until (.Values.server.replicas | int) }} + {{- range $index := until (toString (.Values.server.replicas) | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} -server @@ -176,7 +176,7 @@ spec: {{- if .Values.server.nodeSelector }} nodeSelector: {{ tpl .Values.server.nodeSelector . | indent 8 | trim }} - {{- end }} + {{- end }} volumeClaimTemplates: - metadata: name: data-{{ .Release.Namespace }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 4501896f33..37c52960ee 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -72,6 +72,21 @@ load _helpers [ "${actual}" = "null" ] } +#-------------------------------------------------------------------- +# retry-join + +@test "server/StatefulSet: retry join gets populated" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.replicas=3' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | any(contains("-retry-join"))' | tee /dev/stderr) + + [ "${actual}" = "true" ] +} + + #-------------------------------------------------------------------- # grpc diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 35df8c4c4c..f98979911c 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -42,6 +42,20 @@ load _helpers [ "${actual}" = "false" ] } +#-------------------------------------------------------------------- +# retry-join + +@test "server/StatefulSet: retry join gets populated" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.replicas=3' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command | any(contains("-retry-join"))' | tee /dev/stderr) + + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # image From c2a47800c556ad0b8bacee3c7c357662ec2b9725 Mon Sep 17 00:00:00 2001 From: Tim Colbert Date: Thu, 24 Oct 2019 10:32:40 +1000 Subject: [PATCH 244/739] Revert change to int/string ensure tests complete --- templates/_helpers.tpl | 6 +++--- templates/client-daemonset.yaml | 2 +- templates/server-statefulset.yaml | 4 ++-- test/unit/client-daemonset.bats | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 176b74d404..7333b4ab01 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -35,15 +35,15 @@ use the integer value Add a special case for replicas=1, where it should default to 0 as well. */}} {{- define "consul.pdb.maxUnavailable" -}} -{{- if eq (int (toString .Values.server.replicas)) 1 -}} +{{- if eq (int .Values.server.replicas) 1 -}} {{ 0 }} {{- else if .Values.server.disruptionBudget.maxUnavailable -}} {{ .Values.server.disruptionBudget.maxUnavailable -}} {{- else -}} -{{- if eq (int (toString .Values.server.replicas)) 3 -}} +{{- if eq (int .Values.server.replicas) 3 -}} {{- 1 -}} {{- else -}} -{{- sub (div (int (toString .Values.server.replicas)) 2) 1 -}} +{{- sub (div (int .Values.server.replicas) 2) 1 -}} {{- end -}} {{- end -}} {{- end -}} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 07281d76bf..a308f01956 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -128,7 +128,7 @@ spec: {{- end }} {{- else }} {{- if .Values.server.enabled }} - {{- range $index := until (toString (.Values.server.replicas) | int) }} + {{- range $index := until (.Values.server.replicas | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index d0b52cc4f1..21e978f104 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -14,7 +14,7 @@ spec: serviceName: {{ template "consul.fullname" . }}-server podManagementPolicy: Parallel replicas: {{ .Values.server.replicas }} - {{- if (gt (int (toString .Values.server.updatePartition)) 0) }} + {{- if (gt (int .Values.server.updatePartition) 0) }} updateStrategy: type: RollingUpdate rollingUpdate: @@ -118,7 +118,7 @@ spec: {{- if .Values.ui.enabled }} -ui \ {{- end }} - {{- range $index := until (toString (.Values.server.replicas) | int) }} + {{- range $index := until (.Values.server.replicas | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ {{- end }} -server diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 37c52960ee..aee3b560ec 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -75,7 +75,7 @@ load _helpers #-------------------------------------------------------------------- # retry-join -@test "server/StatefulSet: retry join gets populated" { +@test "client/DaemonSet: retry join gets populated" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ From f68a0a85670e6009aafdc9f12460793c0a2ed39e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 28 Oct 2019 15:51:43 -0700 Subject: [PATCH 245/739] Update values.yaml --- values.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 121f00bd5f..4fd0e44eb0 100644 --- a/values.yaml +++ b/values.yaml @@ -430,9 +430,10 @@ connectInject: # See https://www.consul.io/docs/acl/acl-auth-methods.html#binding-rules # and https://www.consul.io/docs/acl/auth-methods/kubernetes.html#trusted-identity-attributes # for more details. + # Requires Consul >= v1.5 and consul-k8s >= v0.8.0. aclBindingRuleSelector: "serviceaccount.name!=default" - # Requires Consul v1.5+ and consul-k8s v0.8.1+ + # Requires Consul >= v1.5 and consul-k8s >= v0.8.1. centralConfig: enabled: false From 2deb7b0b8dd077cdd8be8d1799f5828ff012fc2f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 28 Oct 2019 15:54:43 -0700 Subject: [PATCH 246/739] Upgrade to consul-k8s 0.9.4 --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 4fd0e44eb0..4561fbb5aa 100644 --- a/values.yaml +++ b/values.yaml @@ -25,7 +25,7 @@ global: # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. - imageK8S: "hashicorp/consul-k8s:0.9.3" + imageK8S: "hashicorp/consul-k8s:0.9.4" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running From feb61551a9fced01734bb4b44e4476a0c13d6107 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 28 Oct 2019 16:05:08 -0700 Subject: [PATCH 247/739] Release 0.12.0 --- CHANGELOG.md | 2 +- Chart.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5afc0b0d08..c491754416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## UNRELEASED +## 0.12.0 (Oct 28, 2019) ## 0.11.0 (Oct 15, 2019) diff --git a/Chart.yaml b/Chart.yaml index 85d238a9d5..ce443d6e7f 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.11.0 +version: 0.12.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 341f78520876e1dcc8c5f1d4acf4efd4c93f988e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 28 Oct 2019 16:06:06 -0700 Subject: [PATCH 248/739] Changelog for 0.12.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c491754416..b6d4e6a5b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ ## 0.12.0 (Oct 28, 2019) +IMPROVEMENTS: + + * Use the latest version of consul-k8s (0.9.4) + * Support `bootstrapACLs` when only servers are enabled (not clients) [[GH-250](https://github.com/hashicorp/consul-helm/pull/250)] + * Use less privileges for catalog sync when not syncing to k8s [[GH-248](https://github.com/hashicorp/consul-helm/pull/248)] + * Enable disabling tests for users using `helm template` [[GH-249](https://github.com/hashicorp/consul-helm/pull/249)] + +BUG FIXES: + + * Fix `missing required field "caBundle"` bug [[GH-213](https://github.com/hashicorp/consul-helm/issues/213)] + + ## 0.11.0 (Oct 15, 2019) IMPROVEMENTS: From 56be9a69bc9ab64f21ee6170ac3aa43f817fab8d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 31 Oct 2019 12:46:06 -0700 Subject: [PATCH 249/739] Allow setting the -acl-auth-method flag For users that are setting up ACLs themselves (e.g. they have external Consul servers so can't use bootstrapACLs) this allows them to create their own Kubernetes auth method that the init container will use during connect injection to receive an ACL token. Fixes https://github.com/hashicorp/consul-k8s/issues/131 --- templates/connect-inject-deployment.yaml | 4 +- test/unit/connect-inject-deployment.bats | 47 ++++++++++++++++++++++++ values.yaml | 4 ++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index aefcebe78c..bec17e75f3 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -52,7 +52,9 @@ spec: -envoy-image="{{ .Values.connectInject.imageEnvoy }}" \ {{ end -}} -listen=:8080 \ - {{- if .Values.global.bootstrapACLs }} + {{- if .Values.connectInject.overrideAuthMethodName }} + -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ + {{ else if .Values.global.bootstrapACLs }} -acl-auth-method="{{ .Release.Name }}-consul-k8s-auth-method" \ {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index fd60a4dd61..4a5783810b 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -270,3 +270,50 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-default-protocol=\"grpc\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# authMethod + +@test "connectInject/Deployment: -acl-auth-method is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method="))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: -acl-auth-method is set when global.bootstrapACLs is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"release-name-consul-k8s-auth-method\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: -acl-auth-method is set to connectInject.overrideAuthMethodName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.overrideAuthMethodName=override' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"override\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: -acl-auth-method is overridden by connectInject.overrideAuthMethodName if global.bootstrapACLs is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'connectInject.overrideAuthMethodName=override' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"override\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 4561fbb5aa..52045de9ee 100644 --- a/values.yaml +++ b/values.yaml @@ -433,6 +433,10 @@ connectInject: # Requires Consul >= v1.5 and consul-k8s >= v0.8.0. aclBindingRuleSelector: "serviceaccount.name!=default" + # If not using global.bootstrapACLs and instead manually setting up an auth + # method for Connect inject, set this to the name of your auth method. + overrideAuthMethodName: "" + # Requires Consul >= v1.5 and consul-k8s >= v0.8.1. centralConfig: enabled: false From 2bbfcc4453f60f27c98ffd117443498cceb9981e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 7 Nov 2019 14:23:53 -0800 Subject: [PATCH 250/739] Help prevent incorrect connectInject config Connect injection requires clients to be enabled and the gRPC port to be enabled. These requirements are documented on the website although not in the values.yaml itself. If users do not enable clients, their init pods will fail. If users do not enable gRPC, their sidecars will be reported as unhealthy. Both these outcomes are hard to debug. This change makes it harder to get into this misconfiguration. It will cause a helm error if clients or grpc are not enabled when connect is enabled. It also defaults client.grpc to true. There are no downsides to having the grpc port open even if not using connect inject. This change means enabling connect simply requires setting connectInject to true rather than also setting client.grpc to true (something that's unintuitive and easy to miss). This is a breaking change, however any users that had connect enabled but clients or gRPC not enabled would be running into errors so it's not going to break anything for anyone that isn't already in a broken state. --- CHANGELOG.md | 9 ++++ templates/connect-inject-deployment.yaml | 2 + test/unit/client-daemonset.bats | 10 ++--- ...connect-inject-authmethod-clusterrole.bats | 1 + ...-inject-authmethod-clusterrolebinding.bats | 1 + ...nect-inject-authmethod-serviceaccount.bats | 1 + test/unit/connect-inject-clusterrole.bats | 1 + .../connect-inject-clusterrolebinding.bats | 1 + test/unit/connect-inject-deployment.bats | 45 ++++++++++++++++++- test/unit/connect-inject-mutatingwebhook.bats | 1 + test/unit/connect-inject-service.bats | 1 + test/unit/connect-inject-serviceaccount.bats | 1 + values.yaml | 9 ++-- 13 files changed, 74 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d4e6a5b4..7ff295fd45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## Unreleased + +BREAKING CHANGES + * `client.grpc` defaults to `true` now instead of `false`. This is to make it + harder to misconfigure connect [[GH-282](https://github.com/hashicorp/consul-helm/pull/282)] + + If you wish to not have client grpc ports exposed, set `client.grpc` to + `false` in your local values file. + ## 0.12.0 (Oct 28, 2019) IMPROVEMENTS: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index aefcebe78c..1b6f20b866 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -1,5 +1,7 @@ # The deployment for running the Connect sidecar injector {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled for connect injection" }}{{ end }} +{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true for connect injection" }}{{ end }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index aee3b560ec..fcffaa31b2 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -90,23 +90,23 @@ load _helpers #-------------------------------------------------------------------- # grpc -@test "client/DaemonSet: grpc is disabled by default" { +@test "client/DaemonSet: grpc is enabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("grpc"))' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } -@test "client/DaemonSet: grpc can be enabled" { +@test "client/DaemonSet: grpc can be disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'client.grpc=true' \ + --set 'client.grpc=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("grpc"))' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } #-------------------------------------------------------------------- diff --git a/test/unit/connect-inject-authmethod-clusterrole.bats b/test/unit/connect-inject-authmethod-clusterrole.bats index 6c5b2774cf..e7427e3793 100644 --- a/test/unit/connect-inject-authmethod-clusterrole.bats +++ b/test/unit/connect-inject-authmethod-clusterrole.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-authmethod-clusterrole.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'global.bootstrapACLs=true' \ . | tee /dev/stderr | diff --git a/test/unit/connect-inject-authmethod-clusterrolebinding.bats b/test/unit/connect-inject-authmethod-clusterrolebinding.bats index 54ee11c8d8..7375da3a0e 100644 --- a/test/unit/connect-inject-authmethod-clusterrolebinding.bats +++ b/test/unit/connect-inject-authmethod-clusterrolebinding.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'global.bootstrapACLs=true' \ . | tee /dev/stderr | diff --git a/test/unit/connect-inject-authmethod-serviceaccount.bats b/test/unit/connect-inject-authmethod-serviceaccount.bats index 1089ab35a4..e2b8d63b3e 100644 --- a/test/unit/connect-inject-authmethod-serviceaccount.bats +++ b/test/unit/connect-inject-authmethod-serviceaccount.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-authmethod-serviceaccount.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'global.bootstrapACLs=true' \ . | tee /dev/stderr | diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats index 2852f53c82..45b5c7cbc3 100644 --- a/test/unit/connect-inject-clusterrole.bats +++ b/test/unit/connect-inject-clusterrole.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) diff --git a/test/unit/connect-inject-clusterrolebinding.bats b/test/unit/connect-inject-clusterrolebinding.bats index 3e21eec14b..6cb38cdaa5 100644 --- a/test/unit/connect-inject-clusterrolebinding.bats +++ b/test/unit/connect-inject-clusterrolebinding.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-clusterrolebinding.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index fd60a4dd61..f7a121ed79 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -11,11 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/Deployment: enable with global.enabled false" { +@test "connectInject/Deployment: enable with global.enabled false, client.enabled true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -42,6 +43,48 @@ load _helpers [ "${actual}" = "false" ] } +@test "connectInject/Deployment: fails if global.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enabled=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled for connect injection" ]] +} + +@test "connectInject/Deployment: fails if global.enabled=true and client.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enabled=true' \ + --set 'client.enabled=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled for connect injection" ]] +} + +@test "connectInject/Deployment: fails if global.enabled=false and client.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enabled=false' \ + --set 'client.enabled=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled for connect injection" ]] +} + +@test "connectInject/Deployment: fails if client.grpc=false" { + cd `chart_dir` + run helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'client.grpc=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "client.grpc must be true for connect injection" ]] +} + #-------------------------------------------------------------------- # consul and envoy images diff --git a/test/unit/connect-inject-mutatingwebhook.bats b/test/unit/connect-inject-mutatingwebhook.bats index dd06f9cb9a..994fe38d26 100755 --- a/test/unit/connect-inject-mutatingwebhook.bats +++ b/test/unit/connect-inject-mutatingwebhook.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-mutatingwebhook.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/connect-inject-service.bats b/test/unit/connect-inject-service.bats index e9a819c75a..6bb6e655f0 100755 --- a/test/unit/connect-inject-service.bats +++ b/test/unit/connect-inject-service.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-service.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/connect-inject-serviceaccount.bats b/test/unit/connect-inject-serviceaccount.bats index e5b3a5a790..8c3944a9e1 100644 --- a/test/unit/connect-inject-serviceaccount.bats +++ b/test/unit/connect-inject-serviceaccount.bats @@ -16,6 +16,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-serviceaccount.yaml \ --set 'global.enabled=false' \ + --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) diff --git a/values.yaml b/values.yaml index 4561fbb5aa..38887f29ef 100644 --- a/values.yaml +++ b/values.yaml @@ -167,9 +167,9 @@ client: image: null join: null - # grpc should be set to true if the gRPC listener should be enabled. + # If true, Consul's gRPC port will be exposed (see https://www.consul.io/docs/agent/options.html#grpc_port). # This should be set to true if connectInject or meshGateway is enabled. - grpc: false + grpc: true # Resource requests, limits, etc. for the client cluster placement. This # should map directly to the value of the resources field for a PodSpec, @@ -308,7 +308,8 @@ ui: # enabled then set the node selection so that it chooses a node with a # Consul agent. syncCatalog: - # True if you want to enable the catalog sync. "-" for default. + # True if you want to enable the catalog sync. Set to "-" to inherit from + # global.enabled. enabled: false image: null default: true # true will sync by default, otherwise requires annotation @@ -374,6 +375,8 @@ syncCatalog: # ConnectInject will enable the automatic Connect sidecar injector. connectInject: + # True if you want to enable connect injection. Set to "-" to inherit from + # global.enabled. enabled: false image: null # image for consul-k8s that contains the injector default: false # true will inject by default, otherwise requires annotation From 9996bcb657b286d7a75d79e2f594994bfd7a0829 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 26 Nov 2019 11:11:51 -0800 Subject: [PATCH 251/739] Bump default consul version to 1.6.2 --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index 52045de9ee..889404ad7a 100644 --- a/values.yaml +++ b/values.yaml @@ -16,7 +16,7 @@ global: # Examples: # image: "consul:1.5.0" # image: "hashicorp/consul-enterprise:1.5.0-ent" # Enterprise Consul image - image: "consul:1.6.1" + image: "consul:1.6.2" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as the catalog sync. This can be overridden From f92eac1fe91145330f3a28771d603bfe036f8a4c Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 26 Nov 2019 15:45:53 -0800 Subject: [PATCH 252/739] Apply suggestions from code review Co-Authored-By: Iryna Shustava --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ff295fd45..7b28f8cfe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,9 @@ BREAKING CHANGES * `client.grpc` defaults to `true` now instead of `false`. This is to make it - harder to misconfigure connect [[GH-282](https://github.com/hashicorp/consul-helm/pull/282)] + harder to misconfigure Connect [[GH-282](https://github.com/hashicorp/consul-helm/pull/282)] - If you wish to not have client grpc ports exposed, set `client.grpc` to + If you do not wish to enable gRPC for clients, set `client.grpc` to `false` in your local values file. ## 0.12.0 (Oct 28, 2019) From 24ba28017ed14b5a4dcab6dcc0f4392d60a28c8b Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 26 Nov 2019 12:12:25 -0800 Subject: [PATCH 253/739] Do not run server-acl-init during server rollout Prior to this change, running helm upgrade with server.updatePartition > 0 and global.bootstrapACLs=true would cause the command to hang indefinitely. It would hang because it waited for the server-acl-init-cleanup hook to complete. This hook would not complete until the server-acl-init job finished. This job would not finish because it waits until the server rollout is complete. The server rollout would not complete because the updatePartition causes one server at a time to roll out. In order for the server rollout to complete, the user needs to wait for the first server to be upgraded, then they need to decrease the updatePartition by one and then run helm upgrade again and repeat until all the servers are upgraded. In order to fix this, this change causes the server-acl-init job to only run when the updatePartition is 0. This means during a server rollout, i.e. updatePartition > 0, the job won't run and so the cleanup hook will exit immediately and the helm upgrade command will exit cleanly. Once the last server is ready to be upgraded, the updatePartition will be set to 0. When helm upgrade runs, the server-acl-init Job will be rendered but it will be able to complete successfully once that final server comes up because the rollout will be complete. It's worth noting that the reason we run server-acl-init during helm upgrade is to help in the case when users have enabled a new feature, for example mesh gateways, and need acl tokens for that feature. --- templates/server-acl-init-cleanup-job.yaml | 3 +++ templates/server-acl-init-job.yaml | 9 +++++++++ test/unit/server-acl-init-cleanup-job.bats | 11 +++++++++++ test/unit/server-acl-init-job.bats | 11 +++++++++++ 4 files changed, 34 insertions(+) diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index 9ad32e92d3..11617fbe5a 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,5 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} +{{- /* See reason for this in server-acl-init-job.yaml */ -}} +{{- if eq (int .Values.server.updatePartition) 0 }} # This job deletes the server-acl-init job once it completes successfully. # It runs as a helm hook because it only needs to run when the server-acl-init # Job gets recreated which only happens during an install or upgrade. @@ -51,3 +53,4 @@ spec: - {{ template "consul.fullname" . }}-server-acl-init {{- end }} {{- end }} + {{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 996bcdb03e..279ee71362 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,5 +1,13 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.bootstrapACLs }} +{{- /* We don't render this job when server.updatePartition > 0 because that + means a server rollout is in progress and this job won't complete unless + the rollout is finished (which won't happen until the partition is 0). + If we ran it in this case, then the job would not complete which would cause + the server-acl-init-cleanup hook to run indefinitely which would cause the + helm upgrade command to hang. +*/ -}} +{{- if eq (int .Values.server.updatePartition) 0 }} apiVersion: batch/v1 kind: Job metadata: @@ -66,3 +74,4 @@ spec: -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} +{{- end }} diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index 42f2628a3a..56dbee2411 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -43,6 +43,17 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInitCleanup/Job: disabled when server.updatePartition > 0" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.updatePartition=1' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "serverACLInitCleanup/Job: consul-k8s delete-completed-job is called with correct arguments" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 1f674d1c2c..682fcc6637 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -43,6 +43,17 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/Job: disabled when server.updatePartition > 0" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'server.updatePartition=1' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { cd `chart_dir` local actual=$(helm template \ From 6cc50a3609524a053cd48154edda97128ef19801 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 28 Nov 2019 09:38:44 -0800 Subject: [PATCH 254/739] Move contributing docs to contributing.md Most people looking at the readme won't want to read the docs about contributing and they may be confusing so I've moved them to contributing.md. I've also removed the line about which Kubernetes versions we've tested against since it implies that the chart might not work with 13,14,15 or 16, which is incorrect. Since we don't currently have a process for testing against new Kube versions and updating our README I thought it best to leave it out. --- CONTRIBUTING.md | 166 +++++++++++++++++++++++++++++++++++++++++++++++ README.md | 167 +----------------------------------------------- 2 files changed, 167 insertions(+), 166 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..25bc3cea19 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,166 @@ +# Contributing + +## Rebasing contributions against master + +PRs in this repo are merged using the [`rebase`](https://git-scm.com/docs/git-rebase) method. This keeps +the git history clean by adding the PR commits to the most recent end of the commit history. It also has +the benefit of keeping all the relevant commits for a given PR together, rather than spread throughout the +git history based on when the commits were first created. + +If the changes in your PR do not conflict with any of the existing code in the project, then Github supports +automatic rebasing when the PR is accepted into the code. However, if there are conflicts (there will be +a warning on the PR that reads "This branch cannot be rebased due to conflicts"), you will need to manually +rebase the branch on master, fixing any conflicts along the way before the code can be merged. + +## Testing + +The Helm chart ships with both unit and acceptance tests. + +The unit tests don't require any active Kubernetes cluster and complete +very quickly. These should be used for fast feedback during development. +The acceptance tests require a Kubernetes cluster with a configured `kubectl`. + +### Prequisites +* [Bats](https://github.com/bats-core/bats-core) + ```bash + brew install bats-core + ``` +* [yq](https://pypi.org/project/yq/) + ```bash + brew install python-yq + ``` +* [helm](https://helm.sh) + ```bash + brew install kubernetes-helm + ``` + +### Running The Tests +To run the unit tests: + + bats ./test/unit + +To run the acceptance tests: + + bats ./test/acceptance + +If the acceptance tests fail, deployed resources in the Kubernetes cluster +may not be properly cleaned up. We recommend recycling the Kubernetes cluster to +start from a clean slate. + +**Note:** There is a Terraform configuration in the +[`test/terraform/`](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) directory +that can be used to quickly bring up a GKE cluster and configure +`kubectl` and `helm` locally. This can be used to quickly spin up a test +cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes +cluster. + +### Writing Unit Tests + +Changes to the Helm chart should be accompanied by appropriate unit tests. + +#### Formatting + +- Put tests in the test file in the same order as the variables appear in the `values.yaml`. +- Start tests for a chart value with a header that says what is being tested, like this: + ``` + #-------------------------------------------------------------------- + # annotations + ``` + +- Name the test based on what it's testing in the following format (this will be its first line): + ``` + @test "
: " { + ``` + + When adding tests to an existing file, the first section will be the same as the other tests in the file. + +#### Test Details + +[Bats](https://github.com/bats-core/bats-core) provides a way to run commands in a shell and inspect the output in an automated way. +In all of the tests in this repo, the base command being run is [helm template](https://docs.helm.sh/helm/#helm-template) which turns the templated files into straight yaml output. +In this way, we're able to test that the various conditionals in the templates render as we would expect. + +Each test defines the files that should be rendered using the `-x` flag, then it might adjust chart values by adding `--set` flags as well. +The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). +`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). +The `-r` flag can be used with `yq` to return a raw string instead of a quoted one which is especially useful when looking for an exact match. + +The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. + +The `| tee /dev/stderr ` pieces direct any terminal output of the `helm template` and `yq` commands to stderr so that it doesn't interfere with `bats`. + +#### Test Examples + +Here are some examples of common test patterns: + +- Check that a value is disabled by default + + ``` + @test "ui/Service: no type by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "null" ] + } + ``` + + In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. + This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]`. + + +- Check that a template value is rendered to a specific value + ``` + @test "ui/Service: specified type" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'ui.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] + } + ``` + + This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. + +- Check that a template value contains several values + ``` + @test "syncCatalog/Deployment: to-k8s only" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-consul=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.toConsul=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + In this case, the same command is run twice in the same test. + This can be used to look for several things in the same field, or to check that something is not present that shouldn't be. + + *Note:* If testing more than two conditions, it would be good to separate the `helm template` part of the command from the `yq` sections to reduce redundant work. + +- Check that an entire template file is not rendered + ``` + @test "syncCatalog/Deployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + Here we are check the length of the command output to see if the anything is rendered. + This style can easily be switched to check that a file is rendered instead. diff --git a/README.md b/README.md index 20b524b49a..ea999cc7d4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The versions required are: it works with earlier versions but this chart is untested for those versions. * **Kubernetes 1.9+** - This is the earliest version of Kubernetes tested. It is possible that this chart works with earlier versions but it is - untested. Other versions verified are Kubernetes 1.10, 1.11. + untested. ## Usage @@ -36,168 +36,3 @@ then be installed directly: Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the [Consul website](https://www.consul.io/docs/platform/k8s/helm.html). - -## Rebasing contributions against master - -PRs in this repo are merged using the [`rebase`](https://git-scm.com/docs/git-rebase) method. This keeps -the git history clean by adding the PR commits to the most recent end of the commit history. It also has -the benefit of keeping all the relevant commits for a given PR together, rather than spread throughout the -git history based on when the commits were first created. - -If the changes in your PR do not conflict with any of the existing code in the project, then Github supports -automatic rebasing when the PR is accepted into the code. However, if there are conflicts (there will be -a warning on the PR that reads "This branch cannot be rebased due to conflicts"), you will need to manually -rebase the branch on master, fixing any conflicts along the way before the code can be merged. - -## Testing - -The Helm chart ships with both unit and acceptance tests. - -The unit tests don't require any active Kubernetes cluster and complete -very quickly. These should be used for fast feedback during development. -The acceptance tests require a Kubernetes cluster with a configured `kubectl`. - -### Prequisites -* [Bats](https://github.com/bats-core/bats-core) - ```bash - brew install bats-core - ``` -* [yq](https://pypi.org/project/yq/) - ```bash - brew install python-yq - ``` -* [helm](https://helm.sh) - ```bash - brew install kubernetes-helm - ``` - -### Running The Tests -To run the unit tests: - - bats ./test/unit - -To run the acceptance tests: - - bats ./test/acceptance - -If the acceptance tests fail, deployed resources in the Kubernetes cluster -may not be properly cleaned up. We recommend recycling the Kubernetes cluster to -start from a clean slate. - -**Note:** There is a Terraform configuration in the -[`test/terraform/`](https://github.com/hashicorp/consul-helm/tree/master/test/terraform) directory -that can be used to quickly bring up a GKE cluster and configure -`kubectl` and `helm` locally. This can be used to quickly spin up a test -cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes -cluster. - -### Writing Unit Tests - -Changes to the Helm chart should be accompanied by appropriate unit tests. - -#### Formatting - -- Put tests in the test file in the same order as the variables appear in the `values.yaml`. -- Start tests for a chart value with a header that says what is being tested, like this: - ``` - #-------------------------------------------------------------------- - # annotations - ``` - -- Name the test based on what it's testing in the following format (this will be its first line): - ``` - @test "
: " { - ``` - - When adding tests to an existing file, the first section will be the same as the other tests in the file. - -#### Test Details - -[Bats](https://github.com/bats-core/bats-core) provides a way to run commands in a shell and inspect the output in an automated way. -In all of the tests in this repo, the base command being run is [helm template](https://docs.helm.sh/helm/#helm-template) which turns the templated files into straight yaml output. -In this way, we're able to test that the various conditionals in the templates render as we would expect. - -Each test defines the files that should be rendered using the `-x` flag, then it might adjust chart values by adding `--set` flags as well. -The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). -`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). -The `-r` flag can be used with `yq` to return a raw string instead of a quoted one which is especially useful when looking for an exact match. - -The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. - -The `| tee /dev/stderr ` pieces direct any terminal output of the `helm template` and `yq` commands to stderr so that it doesn't interfere with `bats`. - -#### Test Examples - -Here are some examples of common test patterns: - -- Check that a value is disabled by default - - ``` - @test "ui/Service: no type by default" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/ui-service.yaml \ - . | tee /dev/stderr | - yq -r '.spec.type' | tee /dev/stderr) - [ "${actual}" = "null" ] - } - ``` - - In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. - This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]`. - - -- Check that a template value is rendered to a specific value - ``` - @test "ui/Service: specified type" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/ui-service.yaml \ - --set 'ui.service.type=LoadBalancer' \ - . | tee /dev/stderr | - yq -r '.spec.type' | tee /dev/stderr) - [ "${actual}" = "LoadBalancer" ] - } - ``` - - This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. - -- Check that a template value contains several values - ``` - @test "syncCatalog/Deployment: to-k8s only" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/sync-catalog-deployment.yaml \ - --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.toConsul=false' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-to-consul=false"))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - local actual=$(helm template \ - -x templates/sync-catalog-deployment.yaml \ - --set 'syncCatalog.enabled=true' \ - --set 'syncCatalog.toConsul=false' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-to-k8s"))' | tee /dev/stderr) - [ "${actual}" = "false" ] - } - ``` - In this case, the same command is run twice in the same test. - This can be used to look for several things in the same field, or to check that something is not present that shouldn't be. - - *Note:* If testing more than two conditions, it would be good to separate the `helm template` part of the command from the `yq` sections to reduce redundant work. - -- Check that an entire template file is not rendered - ``` - @test "syncCatalog/Deployment: disabled by default" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/sync-catalog-deployment.yaml \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] - } - ``` - Here we are check the length of the command output to see if the anything is rendered. - This style can easily be switched to check that a file is rendered instead. From fb3c956915243ffd049bb41dedfb111c057897f3 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 27 Nov 2019 14:54:44 -0800 Subject: [PATCH 255/739] Better document namespaceSelector. Make it clear that this value is not simply the name of the namespace but a specific object. --- values.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/values.yaml b/values.yaml index 7c93899ccf..23e8bd756b 100644 --- a/values.yaml +++ b/values.yaml @@ -390,6 +390,12 @@ connectInject: # namespaceSelector is the selector for restricting the webhook to only # specific namespaces. This should be set to a multiline string. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # Example: + # namespaceSelector: | + # matchLabels: + # namespace-label: label-value namespaceSelector: null # The certs section configures how the webhook TLS certs are configured. From a0c317a632900769e1c77cfa0313d76e47fcc5a2 Mon Sep 17 00:00:00 2001 From: Steve Dillon Date: Wed, 16 Oct 2019 16:06:29 -0400 Subject: [PATCH 256/739] Change the --advertise address to the HostIP and make ports 8301,8302 type hostPort. This will allow a client on a Kubernetes node talk to an external consul cluster. I modified a unit test that was failing before my changes. I'm sure it's just my machine , but the unit test was using the regex jq test filter I changed the filter to 'contains' as there wasn't a need for regex for this comparision and it now works in my environment. --- templates/client-daemonset.yaml | 40 ++++++++++++++++++--- test/unit/client-daemonset.bats | 64 ++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index a308f01956..88fe1f7d93 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -74,10 +74,18 @@ spec: - name: consul image: "{{ default .Values.global.image .Values.client.image }}" env: - - name: POD_IP + - name: ADVERTISE_IP valueFrom: fieldRef: + {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + # The server is enabled, which we make the assumption that this is a contained environment and + # the pods do not need to be exposed, and need to run on Pod IP's to talk to the server (also on pod ips) fieldPath: status.podIP + {{- else }} + # we are not going to be running a server on this cluster, so have the client listen on NodePorts + # so that it can communicate bidirectionally with servers outside the cluster. + fieldPath: status.hostIP + {{- end }} - name: NAMESPACE valueFrom: fieldRef: @@ -102,7 +110,7 @@ spec: exec /bin/consul agent \ -node="${NODE}" \ - -advertise="${POD_IP}" \ + -advertise="${ADVERTISE_IP}" \ -bind=0.0.0.0 \ -client=0.0.0.0 \ {{- if .Values.client.grpc }} @@ -163,10 +171,34 @@ spec: hostPort: 8502 name: grpc - containerPort: 8301 - name: serflan + {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + # We are not installing server, take the host port which allows an external server to connect. + hostPort: 8301 + {{- end }} + protocol: "TCP" + name: serflan-tcp + - containerPort: 8301 + {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + hostPort: 8301 + {{- end }} + protocol: "UDP" + name: serflan-udp - containerPort: 8302 - name: serfwan + {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + hostPort: 8302 + {{- end }} + protocol: "TCP" + name: serfwan-tcp + - containerPort: 8302 + {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + hostPort: 8302 + {{- end }} + protocol: "UDP" + name: serfwan-udp - containerPort: 8300 + {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + hostPort: 8300 + {{- end }} name: server - containerPort: 8600 name: dns-tcp diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index fcffaa31b2..3656a92a2b 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -232,7 +232,7 @@ load _helpers --set 'client.extraVolumes[0].name=foo' \ --set 'client.extraVolumes[0].load=true' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | map(select(test("/consul/userconfig/foo"))) | length' | tee /dev/stderr) + yq -r '.spec.template.spec.containers[0].command | map(select(contains("/consul/userconfig/foo"))) | length' | tee /dev/stderr) [ "${actual}" = "1" ] } @@ -506,3 +506,65 @@ load _helpers yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "client/DaemonSet: When Server is enabled, client uses podIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=true' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].env | map(select(.name=="ADVERTISE_IP")) | .[0] | .valueFrom.fieldRef.fieldPath' | + tee /dev/stderr) + [ "${actual}" = "status.podIP" ] +} + +@test "client/DaemonSet: When Server is not enabled, client uses hostIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].env | map(select(.name=="ADVERTISE_IP")) | .[0] | .valueFrom.fieldRef.fieldPath' | + tee /dev/stderr) + [ "${actual}" = "status.hostIP" ] +} + +@test "client/DaemonSet: When Server is not enabled, client uses hostport" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports' | + tee /dev/stderr) + + local actual=$(echo $object | + yq -r 'map(select(.containerPort==8301))| .[0].hostPort' | tee /dev/stderr ) + [ "${actual}" = "8301" ] + local actual=$(echo $object | + yq -r 'map(select(.containerPort==8302))| .[0].hostPort' | tee /dev/stderr ) + [ "${actual}" = "8302" ] + +} +@test "client/DaemonSet: When Server is enable, client doesnt use hostport" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=true' \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports' | + tee /dev/stderr) + + local actual=$(echo $object | + yq -r 'map(select(.containerPort==8301))| .[0].hostPort' | tee /dev/stderr ) + echo "${actual}" + [ "${actual}" = "null" ] + local actual=$(echo $object | + yq -r 'map(select(.containerPort==8302))| .[0].hostPort' | tee /dev/stderr ) + [ "${actual}" = "null" ] + +} \ No newline at end of file From 1f8a35759515ee6197368a42016ab4cb216aa3cb Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Mon, 25 Nov 2019 16:44:10 -0800 Subject: [PATCH 257/739] Switch client gossip port exposure to be configurable Create the `client.exposeGossipPorts` configuration value to trigger the exposure of clients' gossip ports as hostPorts. Updates tests accourdingly. --- templates/client-daemonset.yaml | 28 ++++--------------- test/unit/client-daemonset.bats | 49 +++++++++++++-------------------- values.yaml | 6 ++++ 3 files changed, 31 insertions(+), 52 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 88fe1f7d93..d3b3aa5770 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -77,13 +77,11 @@ spec: - name: ADVERTISE_IP valueFrom: fieldRef: - {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} - # The server is enabled, which we make the assumption that this is a contained environment and - # the pods do not need to be exposed, and need to run on Pod IP's to talk to the server (also on pod ips) + {{- if not .Values.client.exposeGossipPorts }} fieldPath: status.podIP {{- else }} - # we are not going to be running a server on this cluster, so have the client listen on NodePorts - # so that it can communicate bidirectionally with servers outside the cluster. + # Clients will be exposed on their node's hostPort for external-to-k8s communication, + # so they need to advertise their host ip instead of their pod ip. fieldPath: status.hostIP {{- end }} - name: NAMESPACE @@ -171,34 +169,20 @@ spec: hostPort: 8502 name: grpc - containerPort: 8301 - {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} - # We are not installing server, take the host port which allows an external server to connect. + {{- if .Values.client.exposeGossipPorts }} hostPort: 8301 {{- end }} protocol: "TCP" name: serflan-tcp - containerPort: 8301 - {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} + {{- if .Values.client.exposeGossipPorts }} hostPort: 8301 {{- end }} protocol: "UDP" name: serflan-udp - containerPort: 8302 - {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} - hostPort: 8302 - {{- end }} - protocol: "TCP" - name: serfwan-tcp - - containerPort: 8302 - {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} - hostPort: 8302 - {{- end }} - protocol: "UDP" - name: serfwan-udp + name: serfwan - containerPort: 8300 - {{- if not (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} - hostPort: 8300 - {{- end }} name: server - containerPort: 8600 name: dns-tcp diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 3656a92a2b..9e7663b62d 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -507,64 +507,53 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: When Server is enabled, client uses podIP" { +#-------------------------------------------------------------------- +# client.exposeGossipPorts + +@test "client/DaemonSet: client uses podIP when client.exposeGossipPorts=false" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'server.enabled=true' \ --set 'client.enabled=true' \ + --set 'client.exposeGossipPorts=false' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].env | map(select(.name=="ADVERTISE_IP")) | .[0] | .valueFrom.fieldRef.fieldPath' | tee /dev/stderr) [ "${actual}" = "status.podIP" ] } -@test "client/DaemonSet: When Server is not enabled, client uses hostIP" { +@test "client/DaemonSet: client uses hostIP when client.exposeGossipPorts=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ --set 'client.enabled=true' \ + --set 'client.exposeGossipPorts=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].env | map(select(.name=="ADVERTISE_IP")) | .[0] | .valueFrom.fieldRef.fieldPath' | tee /dev/stderr) [ "${actual}" = "status.hostIP" ] } -@test "client/DaemonSet: When Server is not enabled, client uses hostport" { +@test "client/DaemonSet: client doesn't expose hostPorts when client.exposeGossipPorts=false" { cd `chart_dir` - local object=$(helm template \ + local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ + --set 'server.enabled=true' \ --set 'client.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports' | + yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports | map(select(.containerPort==8301)) | .[0].hostPort' | tee /dev/stderr) - - local actual=$(echo $object | - yq -r 'map(select(.containerPort==8301))| .[0].hostPort' | tee /dev/stderr ) - [ "${actual}" = "8301" ] - local actual=$(echo $object | - yq -r 'map(select(.containerPort==8302))| .[0].hostPort' | tee /dev/stderr ) - [ "${actual}" = "8302" ] - + [ "${actual}" = "null" ] } -@test "client/DaemonSet: When Server is enable, client doesnt use hostport" { + +@test "client/DaemonSet: client exposes hostPorts when client.exposeGossipPorts=true" { cd `chart_dir` - local object=$(helm template \ + local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'server.enabled=true' \ --set 'client.enabled=true' \ + --set 'client.exposeGossipPorts=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports' | + yq '.spec.template.spec.containers | map(select(.name=="consul")) | .[0].ports | map(select(.containerPort==8301)) | .[0].hostPort' | tee /dev/stderr) - - local actual=$(echo $object | - yq -r 'map(select(.containerPort==8301))| .[0].hostPort' | tee /dev/stderr ) - echo "${actual}" - [ "${actual}" = "null" ] - local actual=$(echo $object | - yq -r 'map(select(.containerPort==8302))| .[0].hostPort' | tee /dev/stderr ) - [ "${actual}" = "null" ] - -} \ No newline at end of file + [ "${actual}" = "8301" ] +} diff --git a/values.yaml b/values.yaml index 23e8bd756b..16f41ee67f 100644 --- a/values.yaml +++ b/values.yaml @@ -171,6 +171,12 @@ client: # This should be set to true if connectInject or meshGateway is enabled. grpc: true + # exposeGossipPorts exposes the clients' gossip ports as hostPorts. + # This is only necessary if pod IPs in the k8s cluster are not directly + # routable and the Consul servers are outside of the k8s cluster. This + # also changes the clients' advertised IP to the hostIP rather than podIP. + exposeGossipPorts: false + # Resource requests, limits, etc. for the client cluster placement. This # should map directly to the value of the resources field for a PodSpec, # formatted as a multi-line string. By default no direct resource request From 96639c2d4e597575474295306687167fca613ee4 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 4 Dec 2019 16:09:36 -0800 Subject: [PATCH 258/739] Update PodSecurityPolicy for exposeGossipPorts --- templates/client-podsecuritypolicy.yaml | 8 ++++++++ test/unit/client-podsecuritypolicy.bats | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 87a44227a4..411aae53b4 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -25,8 +25,16 @@ spec: - 'downwardAPI' hostNetwork: false hostPorts: + # HTTP Port - min: 8500 + max: 8500 + # gRPC Port + - min: 8502 max: 8502 + {{- if .Values.client.exposeGossipPorts }} + - min: 8301 + max: 8301 + {{- end }} hostIPC: false hostPID: false runAsUser: diff --git a/test/unit/client-podsecuritypolicy.bats b/test/unit/client-podsecuritypolicy.bats index 9cea7ea380..4e9a1b28d4 100644 --- a/test/unit/client-podsecuritypolicy.bats +++ b/test/unit/client-podsecuritypolicy.bats @@ -31,3 +31,17 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# client.exposeGossipPorts + +@test "client/PodSecurityPolicy: hostPort 8301 allowed when exposeGossipPorts=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.exposeGossipPorts=true' \ + . | tee /dev/stderr | + yq -c '.spec.hostPorts' | tee /dev/stderr) + [ "${actual}" = '[{"min":8500,"max":8500},{"min":8502,"max":8502},{"min":8301,"max":8301}]' ] +} From 11b76fb7209747586add9ced29fc17290d3e38d8 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 5 Dec 2019 17:59:26 -0800 Subject: [PATCH 259/739] syncCatalog: expose add-k8s-namespace-suffix flag (#280) * syncCatalog: add `addK8SNamespaceSuffix` property and set it to true by default. This is a breaking change because an upgrade to this version will unregister all services in Consul and register them with a new name. --- templates/sync-catalog-deployment.yaml | 3 +++ test/unit/sync-catalog-deployment.bats | 24 ++++++++++++++++++++++++ values.yaml | 20 ++++++++++++++++---- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index e463b346d2..ad57a0ef03 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -94,6 +94,9 @@ spec: {{- if .Values.syncCatalog.consulPrefix}} -consul-service-prefix="{{ .Values.syncCatalog.consulPrefix}}" \ {{- end}} + {{- if .Values.syncCatalog.addK8SNamespaceSuffix}} + -add-k8s-namespace-suffix \ + {{- end}} livenessProbe: httpGet: path: /health/ready diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 5f7179681b..306b707444 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -371,3 +371,27 @@ load _helpers yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# addK8SNamespaceSuffix + +@test "syncCatalog/Deployment: k8s namespace suffix enabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-add-k8s-namespace-suffix"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: can set addK8SNamespaceSuffix to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.addK8SNamespaceSuffix=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-add-k8s-namespace-suffix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 16f41ee67f..bc14b2587f 100644 --- a/values.yaml +++ b/values.yaml @@ -25,7 +25,7 @@ global: # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. - imageK8S: "hashicorp/consul-k8s:0.9.4" + imageK8S: "hashicorp/consul-k8s:0.9.5" # Datacenter is the name of the datacenter that the agents should register # as. This shouldn't be changed once the Consul cluster is up and running @@ -271,7 +271,7 @@ client: # https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers dns: enabled: "-" - + # Set a predefined cluster IP for the DNS service. # Useful if you need to reference the DNS service's IP # address in CoreDNS config. @@ -335,10 +335,22 @@ syncCatalog: # to all namespaces. k8sSourceNamespace: null - # consulPrefix is the service prefix which preprends itself + # addK8SNamespaceSuffix appends Kubernetes namespace suffix to + # each service name synced to Consul, separated by a dash. + # For example, for a service 'foo' in the default namespace, + # the sync process will create a Consul service named 'foo-default'. + # Set this flag to true to avoid registering services with the same name + # but in different namespaces as instances for the same Consul service. + # Namespace suffix is not added if 'annotationServiceName' is provided. + addK8SNamespaceSuffix: true + + # consulPrefix is the service prefix which prepends itself # to Kubernetes services registered within Consul - # For example, "k8s-" will register all services peprended with "k8s-". + # For example, "k8s-" will register all services prepended with "k8s-". # (Kubernetes -> Consul sync) + # consulPrefix is ignored when 'annotationServiceName' is provided. + # NOTE: Updating this property to a non-null value for an existing installation will result in deregistering + # of existing services in Consul and registering them with a new name. consulPrefix: null # k8sTag is an optional tag that is applied to all of the Kubernetes services From ff69145becc24965038b5aa130d37f3eef581483 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 5 Dec 2019 18:28:34 -0800 Subject: [PATCH 260/739] Update CHANGELOG.md --- CHANGELOG.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b28f8cfe4..093871eb21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,30 @@ ## Unreleased -BREAKING CHANGES +BREAKING CHANGES: + * `client.grpc` defaults to `true` now instead of `false`. This is to make it - harder to misconfigure Connect [[GH-282](https://github.com/hashicorp/consul-helm/pull/282)] + harder to misconfigure Connect. [[GH-282](https://github.com/hashicorp/consul-helm/pull/282)] - If you do not wish to enable gRPC for clients, set `client.grpc` to - `false` in your local values file. + If you do not wish to enable gRPC for clients, set `client.grpc` to + `false` in your local values file. + + * Add `syncCatalog.addK8SNamespaceSuffix` and default it to `true`. [[GH-280](https://github.com/hashicorp/consul-helm/pull/280) + Note: upgrading an existing installation will result in deregistering + of existing synced services in Consul and registering them with a new name. + If you would like to avoid this behavior set `syncCatalog.addK8SNamespaceSuffix` + to `false`. + +IMPROVEMENTS: + + * Use the latest version of consul (1.6.2) + * Use the latest version of consul-k8s (0.9.5) + * Add `connectInject.overrideAuthMethodName` to allow setting the `-acl-auth-method flag` [[GH-278](https://github.com/hashicorp/consul-helm/pull/278)] + * Support external to k8s Consul servers [[GH-289](https://github.com/hashicorp/consul-helm/pull/289)] + +BUG FIXES: + + * Add `connectInject.overrideAuthMethodName` to allow setting the `-acl-auth-method flag` [[GH-278](https://github.com/hashicorp/consul-helm/pull/278)] + * Do not run `server-acl-init` during server rollout [[GH-292](https://github.com/hashicorp/consul-helm/pull/292)] ## 0.12.0 (Oct 28, 2019) From be89ea9c33c5259ec1ced102870b0753c3856d44 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 5 Dec 2019 18:32:18 -0800 Subject: [PATCH 261/739] Release 0.13.0 --- CHANGELOG.md | 2 ++ Chart.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 093871eb21..35ea051911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.13.0 (Dec 5, 2019) + BREAKING CHANGES: * `client.grpc` defaults to `true` now instead of `false`. This is to make it diff --git a/Chart.yaml b/Chart.yaml index ce443d6e7f..0d6ec31f29 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.12.0 +version: 0.13.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 0da3ef6e141babd61295592737e7177b15abbc88 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 6 Dec 2019 09:52:37 -0800 Subject: [PATCH 262/739] Update CHANGELOG.md (#305) --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35ea051911..cc883fbc6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,13 @@ BREAKING CHANGES: If you do not wish to enable gRPC for clients, set `client.grpc` to `false` in your local values file. - * Add `syncCatalog.addK8SNamespaceSuffix` and default it to `true`. [[GH-280](https://github.com/hashicorp/consul-helm/pull/280) + * Add `syncCatalog.addK8SNamespaceSuffix` and default it to `true`. [[GH-280](https://github.com/hashicorp/consul-helm/pull/280)] Note: upgrading an existing installation will result in deregistering of existing synced services in Consul and registering them with a new name. If you would like to avoid this behavior set `syncCatalog.addK8SNamespaceSuffix` to `false`. + + This changes the default service names registered from Kubernetes into Consul. Previously, we would register all Kubernetes services, regardless of namespace, as the same service in Consul. After this change, the default behaviour is to append the Kubernetes namespace to the Consul service name. For example, given a Kubernetes service `foo` in the namespace `namespace`, it would be registered in Consul as `foo-namespace`. The name can also be controlled via the `consul.hashicorp.com/service-name` annotation. IMPROVEMENTS: @@ -25,7 +27,6 @@ IMPROVEMENTS: BUG FIXES: - * Add `connectInject.overrideAuthMethodName` to allow setting the `-acl-auth-method flag` [[GH-278](https://github.com/hashicorp/consul-helm/pull/278)] * Do not run `server-acl-init` during server rollout [[GH-292](https://github.com/hashicorp/consul-helm/pull/292)] ## 0.12.0 (Oct 28, 2019) From 0efda8659f61a4e9fa3b7d605895dcfb33b2da5f Mon Sep 17 00:00:00 2001 From: alexshe Date: Tue, 24 Sep 2019 12:12:36 +0300 Subject: [PATCH 263/739] dnsPolicy configuration updateStrategy configuration hostPath persistent storage for consul client data configuration --- templates/client-daemonset.yaml | 15 +++++++++++++++ values.yaml | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index d3b3aa5770..504dc8b0e8 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -11,6 +11,10 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} spec: + {{- if .Values.client.updateStrategy }} + updateStrategy: + {{ toYaml .Values.client.updateStrategy | nindent 4 | trim }} + {{- end }} selector: matchLabels: app: {{ template "consul.name" . }} @@ -47,12 +51,23 @@ spec: priorityClassName: {{ .Values.client.priorityClassName | quote }} {{- end }} + {{- if .Values.client.dnsPolicy }} + dnsPolicy: {{ .Values.client.dnsPolicy }} + {{- end }} + # Consul agents require a directory for data, even clients. The data # is okay to be wiped though if the Pod is removed, so just use an # emptyDir volume. volumes: - name: data + {{- if .Values.client.hostPath }} + hostPath: + # directory location on host + path: {{ .Values.client.hostPath }} + type: DirectoryOrCreate + {{- else }} emptyDir: {} + {{- end }} - name: config configMap: name: {{ template "consul.fullname" . }}-client-config diff --git a/values.yaml b/values.yaml index bc14b2587f..bf08426107 100644 --- a/values.yaml +++ b/values.yaml @@ -263,6 +263,25 @@ client: secretName: null secretKey: null + # updateStrategy for the DaemonSet. + # See https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy. + # This should be a multi-line string mapping directly to the updateStrategy + # Example: + # updateStrategy: + # rollingUpdate: + # maxUnavailable: 5 + # type: RollingUpdate + updateStrategy: null + + # hostPath is fullpath to folder on host machine to mount as /consul/data folder. consul agent stores + # its configuration in this folder. By default its created as emptyDir: {}. To save data between pod restarts + # specify folder name on host machine to be mounted as /consul/data. + # Example: + # hostPath: '/var/consul-data' + hostPath: null + + dnsPolicy: null + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From 59e3ba3542aee0636a44038f2816aa2ab996a23f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 3 Dec 2019 10:55:57 -0800 Subject: [PATCH 264/739] Allow setting hostPath for client data directory client.dataDirectoryHostPath can be set to Mount client data to a host path. This is necessary for the clients to retain any service/check registrations made to them via API. Without this, if a Consul client Pod is deleted, e.g. during a Consul version upgrade, all its Consul Connect registrations are lost. Also allow configuring client dnsPolicy and updateStrategy. --- CHANGELOG.md | 14 +++++ templates/client-daemonset.yaml | 14 ++--- templates/client-podsecuritypolicy.yaml | 8 +++ test/unit/client-daemonset.bats | 78 +++++++++++++++++++++++++ test/unit/client-podsecuritypolicy.bats | 34 +++++++++++ values.yaml | 46 +++++++++------ 6 files changed, 168 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc883fbc6a..77cdfc3c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ ## Unreleased +IMPROVEMENTS: + + * Consul client DaemonSet can now use a [hostPath mount](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) + for its data directory by setting the `client.dataDirectoryHostPath` value. + This setting is currently necessary to ensure that when a Consul client Pod is deleted, + e.g. during a Consul version upgrade, it does not lose its Connect service + registrations. In the next version, we plan to have services automatically + re-register which will remove the need for this. [[GH-298](https://github.com/hashicorp/consul-helm/pull/298)] + + **Security Warning:** If using this setting, Pod Security Policies *must* be enabled on your cluster + and in this Helm chart (via the `global.enablePodSecurityPolicies` setting) + to prevent other Pods from mounting the same host path and gaining + access to all of Consul's data. Consul's data is not encrypted at rest. + ## 0.13.0 (Dec 5, 2019) BREAKING CHANGES: diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 504dc8b0e8..ce05a3dea7 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -13,7 +13,7 @@ metadata: spec: {{- if .Values.client.updateStrategy }} updateStrategy: - {{ toYaml .Values.client.updateStrategy | nindent 4 | trim }} + {{ tpl .Values.client.updateStrategy . | nindent 4 | trim }} {{- end }} selector: matchLabels: @@ -55,15 +55,15 @@ spec: dnsPolicy: {{ .Values.client.dnsPolicy }} {{- end }} - # Consul agents require a directory for data, even clients. The data - # is okay to be wiped though if the Pod is removed, so just use an - # emptyDir volume. + # Consul clients require a directory for data. + # We use a hostPath so that if a Pod is restarted it will retain its + # service and checks registrations. This is important for Consul Connect + # because each Connect Pod registers with the local Consul client. volumes: - name: data - {{- if .Values.client.hostPath }} + {{- if .Values.client.dataDirectoryHostPath }} hostPath: - # directory location on host - path: {{ .Values.client.hostPath }} + path: {{ .Values.client.dataDirectoryHostPath }} type: DirectoryOrCreate {{- else }} emptyDir: {} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 411aae53b4..553e44befe 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -23,6 +23,9 @@ spec: - 'projected' - 'secret' - 'downwardAPI' + {{- if .Values.client.dataDirectoryHostPath }} + - 'hostPath' + {{- end }} hostNetwork: false hostPorts: # HTTP Port @@ -47,4 +50,9 @@ spec: fsGroup: rule: 'RunAsAny' readOnlyRootFilesystem: false + {{- if .Values.client.dataDirectoryHostPath }} + allowedHostPaths: + - pathPrefix: {{ .Values.client.dataDirectoryHostPath | quote }} + readOnly: false + {{- end }} {{- end }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 9e7663b62d..8d29131b5f 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -557,3 +557,81 @@ load _helpers tee /dev/stderr) [ "${actual}" = "8301" ] } + +#-------------------------------------------------------------------- +# dataDirectoryHostPath + +@test "client/DaemonSet: data directory is emptyDir by defaut" { + cd `chart_dir` + # Test that hostPath is set to null. + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[0].hostPath == null' | tee /dev/stderr ) + [ "${actual}" = "true" ] + + # Test that emptyDir is set instead. + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[0].emptyDir == {}' | tee /dev/stderr ) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: hostPath data directory can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.dataDirectoryHostPath=/opt/consul' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[0].hostPath.path == "/opt/consul"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# dnsPolicy + +@test "client/DaemonSet: dnsPolicy not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.dnsPolicy == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: dnsPolicy can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.dnsPolicy=ClusterFirstWithHostNet' \ + . | tee /dev/stderr | + yq '.spec.template.spec.dnsPolicy == "ClusterFirstWithHostNet"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# updateStrategy + +@test "client/DaemonSet: updateStrategy not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | \ + yq '.spec.updateStrategy == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: updateStrategy can be set" { + cd `chart_dir` + local updateStrategy="type: RollingUpdate +rollingUpdate: + maxUnavailable: 5 +" + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set "client.updateStrategy=${updateStrategy}" \ + . | tee /dev/stderr | \ + yq -c '.spec.updateStrategy == {"type":"RollingUpdate","rollingUpdate":{"maxUnavailable":5}}' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/client-podsecuritypolicy.bats b/test/unit/client-podsecuritypolicy.bats index 4e9a1b28d4..8fdfc298ab 100644 --- a/test/unit/client-podsecuritypolicy.bats +++ b/test/unit/client-podsecuritypolicy.bats @@ -45,3 +45,37 @@ load _helpers yq -c '.spec.hostPorts' | tee /dev/stderr) [ "${actual}" = '[{"min":8500,"max":8500},{"min":8502,"max":8502},{"min":8301,"max":8301}]' ] } + +#-------------------------------------------------------------------- +# client.dataDirectoryHostPath + +@test "client/PodSecurityPolicy: disallows hostPath volume by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq '.spec.volumes | any(contains("hostPath"))' | tee /dev/stderr) + [ "${actual}" = 'false' ] +} + +@test "client/PodSecurityPolicy: allows hostPath volume when dataDirectoryHostPath is set" { + cd `chart_dir` + # Test that hostPath is an allowed volume type. + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.dataDirectoryHostPath=/opt/consul' \ + . | tee /dev/stderr | + yq '.spec.volumes | any(contains("hostPath"))' | tee /dev/stderr) + [ "${actual}" = 'true' ] + + # Test that the path we're allowed to write to is the right one. + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.dataDirectoryHostPath=/opt/consul' \ + . | tee /dev/stderr | + yq -r '.spec.allowedHostPaths[0].pathPrefix' | tee /dev/stderr) + [ "${actual}" = '/opt/consul' ] +} diff --git a/values.yaml b/values.yaml index bf08426107..99fdc9b762 100644 --- a/values.yaml +++ b/values.yaml @@ -167,6 +167,20 @@ client: image: null join: null + # dataDirectoryHostPath is an absolute path to a directory on the host machine + # to use as the Consul client data directory. + # If set to the empty string or null, the Consul agent will store its data + # in the Pod's local filesystem (which will be lost if the Pod is deleted). + # If using Consul Connect, this directory must be set. Otherwise when the Consul + # agent Pod is deleted, e.g. during an upgrade, all the Connect-injected Pods + # on that node will be de-registered and will need to be restarted to be + # re-registered. + # Security Warning: If setting this, Pod Security Policies *must* be enabled on your cluster + # and in this Helm chart (via the global.enablePodSecurityPolicies setting) + # to prevent other Pods from mounting the same host path and gaining + # access to all of Consul's data. Consul's data is not encrypted at rest. + dataDirectoryHostPath: null + # If true, Consul's gRPC port will be exposed (see https://www.consul.io/docs/agent/options.html#grpc_port). # This should be set to true if connectInject or meshGateway is enabled. grpc: true @@ -242,6 +256,19 @@ client: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com + # dnsPolicy to use. + dnsPolicy: null + + # updateStrategy for the DaemonSet. + # See https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy. + # This should be a multi-line string mapping directly to the updateStrategy + # Example: + # updateStrategy: | + # rollingUpdate: + # maxUnavailable: 5 + # type: RollingUpdate + updateStrategy: null + # snaphotAgent contains settings for setting up and running snapshot agents # within the Consul clusters. They are required to be co-located with Consul # clients, so will inherit the clients' nodeSelector, tolerations and affinity. @@ -263,25 +290,6 @@ client: secretName: null secretKey: null - # updateStrategy for the DaemonSet. - # See https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy. - # This should be a multi-line string mapping directly to the updateStrategy - # Example: - # updateStrategy: - # rollingUpdate: - # maxUnavailable: 5 - # type: RollingUpdate - updateStrategy: null - - # hostPath is fullpath to folder on host machine to mount as /consul/data folder. consul agent stores - # its configuration in this folder. By default its created as emptyDir: {}. To save data between pod restarts - # specify folder name on host machine to be mounted as /consul/data. - # Example: - # hostPath: '/var/consul-data' - hostPath: null - - dnsPolicy: null - # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From b6421e61760c466705ecf6a3932f8d00f7fda0ca Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 10 Dec 2019 11:09:45 -0800 Subject: [PATCH 265/739] Release 0.14.0 --- CHANGELOG.md | 8 ++++++++ Chart.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77cdfc3c8b..be6406168e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.14.0 (Dec 10, 2019) + IMPROVEMENTS: * Consul client DaemonSet can now use a [hostPath mount](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) @@ -14,6 +16,12 @@ IMPROVEMENTS: to prevent other Pods from mounting the same host path and gaining access to all of Consul's data. Consul's data is not encrypted at rest. + * New configuration option `client.updateStrategy` allows setting the update + strategy for the Client DaemonSet. [[GH-298](https://github.com/hashicorp/consul-helm/pull/298)] + + * New configuration option `client.dnsPolicy` allows setting the DNS + policy for the Client DaemonSet. [[GH-298](https://github.com/hashicorp/consul-helm/pull/298)] + ## 0.13.0 (Dec 5, 2019) BREAKING CHANGES: diff --git a/Chart.yaml b/Chart.yaml index 0d6ec31f29..6fb906e8d0 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.13.0 +version: 0.14.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From c369813efd4430fc90b0effbc3df2676e6521612 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 4 Dec 2019 16:51:33 -0800 Subject: [PATCH 266/739] Default centralConfig to enabled This change will only affect users who have enabled connectInject because we only enable central config if connectInject.enabled is true. Users that are using connectInject are more likely than not going to want to create L7 rules and service-defaults configs because that is where most of the value of Consul Connect lies. Thus enabling this by default makes sense. --- CHANGELOG.md | 11 +++++++++++ test/unit/client-configmap.bats | 14 +++++++------- test/unit/connect-inject-deployment.bats | 10 +++++----- test/unit/mesh-gateway-deployment.bats | 5 +---- test/unit/server-configmap.bats | 20 +++++++------------- values.yaml | 13 ++++++------- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be6406168e..1e15a4d4c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ ## Unreleased +IMPROVEMENTS: + + * `connectInject.centralConfig` defaults to `true` now instead of `false`. This is to make it + easier to configure Connect via `service-defaults` and other routing + config [[GH-302](https://github.com/hashicorp/consul-helm/pull/302)]. + See https://www.consul.io/docs/agent/options.html#enable_central_service_config. + + If you wish to disable central config, set `connectInject.centralConfig` to + false in your local values file. NOTE: If `connectInject.enabled` is false, + then central config is not enabled so this change will not affect you. + ## 0.14.0 (Dec 10, 2019) IMPROVEMENTS: diff --git a/test/unit/client-configmap.bats b/test/unit/client-configmap.bats index f50bbdd331..0e0fbc3679 100755 --- a/test/unit/client-configmap.bats +++ b/test/unit/client-configmap.bats @@ -55,23 +55,23 @@ load _helpers #-------------------------------------------------------------------- # connectInject.centralConfig -@test "client/ConfigMap: centralConfig is disabled by default" { +@test "client/ConfigMap: centralConfig is enabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/client-config-configmap.yaml \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | - yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "client/ConfigMap: centralConfig can be enabled" { +@test "client/ConfigMap: centralConfig can be disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/client-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.enabled=false' \ . | tee /dev/stderr | - yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 70b06738c1..8709ae208e 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -270,25 +270,25 @@ load _helpers #-------------------------------------------------------------------- # centralConfig -@test "connectInject/Deployment: centralConfig is disabled by default" { +@test "connectInject/Deployment: centralConfig is enabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-enable-central-config"))' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } -@test "connectInject/Deployment: centralConfig can be enabled" { +@test "connectInject/Deployment: centralConfig can be disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.enabled=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-enable-central-config"))' | tee /dev/stderr) - [ "${actual}" = "true" ] + [ "${actual}" = "false" ] } @test "connectInject/Deployment: defaultProtocol is disabled by default with centralConfig enabled" { diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 1e05287a05..535dd2f2c9 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -43,8 +43,7 @@ load _helpers -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'client.grpc=false' \ - --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' . + --set 'connectInject.enabled=true' . [ "$status" -eq 1 ] [[ "$output" =~ "client.grpc must be true" ]] } @@ -56,7 +55,6 @@ load _helpers --set 'meshGateway.enabled=true' \ --set 'client.grpc=true' \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'global.enabled=false' . [ "$status" -eq 1 ] [[ "$output" =~ "clients must be enabled" ]] @@ -69,7 +67,6 @@ load _helpers --set 'meshGateway.enabled=true' \ --set 'client.grpc=true' \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'global.enabled=true' \ --set 'client.enabled=false' . [ "$status" -eq 1 ] diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index 388fa9e1b1..e4a26fe800 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -68,25 +68,25 @@ load _helpers #-------------------------------------------------------------------- # connectInject.centralConfig -@test "server/ConfigMap: centralConfig is disabled by default" { +@test "server/ConfigMap: centralConfig is enabled by default" { cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | - yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "server/ConfigMap: centralConfig can be enabled" { +@test "server/ConfigMap: centralConfig can be disabled" { cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ + --set 'connectInject.centralConfig.enabled=false' \ . | tee /dev/stderr | - yq '.data["central-config.json"] | contains("enable_central_service_config")' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq '.data["central-config.json"] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] } @test "server/ConfigMap: proxyDefaults disabled by default" { @@ -94,7 +94,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ . | tee /dev/stderr | yq '.data["proxy-defaults-config.json"] | length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -105,7 +104,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ . | tee /dev/stderr | yq '.data["proxy-defaults-config.json"] | match("world") | length' | tee /dev/stderr) @@ -117,7 +115,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=remote' \ @@ -132,7 +129,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=' \ @@ -147,7 +143,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=null' \ @@ -162,7 +157,6 @@ load _helpers local actual=$(helm template \ -x templates/server-config-configmap.yaml \ --set 'connectInject.enabled=true' \ - --set 'connectInject.centralConfig.enabled=true' \ --set 'connectInject.centralConfig.proxyDefaults=""' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=remote' \ diff --git a/values.yaml b/values.yaml index 99fdc9b762..30b248cabc 100644 --- a/values.yaml +++ b/values.yaml @@ -493,18 +493,17 @@ connectInject: # Requires Consul >= v1.5 and consul-k8s >= v0.8.1. centralConfig: - enabled: false + enabled: true # defaultProtocol allows you to specify a convenience default protocol if # most of your services are of the same protocol type. The individual annotation - # on any given pod will override this value. A protocol must be provided, - # either through this setting or individual annotation, for a service to be - # registered correctly. Valid values are "http", "http2", "grpc" and "tcp". + # on any given pod will override this value. + # Valid values are "http", "http2", "grpc" and "tcp". defaultProtocol: null - # proxyDefaults is a raw json string that will be applied to all Connect - # proxy sidecar pods that can include any valid configuration for the - # configured proxy. + # proxyDefaults is a raw json string that will be written as the value of + # the "config" key of the global proxy-defaults config entry. + # See: https://www.consul.io/docs/agent/config-entries/proxy-defaults.html proxyDefaults: | {} From f154befbaf42aca437f280321b4cb97faa2b7fa0 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 11 Dec 2019 15:10:00 -0800 Subject: [PATCH 267/739] Explain that proxyDefaults doesn't update --- values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/values.yaml b/values.yaml index 30b248cabc..c5e0601bc2 100644 --- a/values.yaml +++ b/values.yaml @@ -504,6 +504,9 @@ connectInject: # proxyDefaults is a raw json string that will be written as the value of # the "config" key of the global proxy-defaults config entry. # See: https://www.consul.io/docs/agent/config-entries/proxy-defaults.html + # NOTE: Changes to this value after the chart is first installed have *no* + # effect. In order to change the proxy-defaults config after installation, + # you must use the Consul API. proxyDefaults: | {} From dd0d0c924c7989a75d08db682c98eb3e83b1ec5f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 12 Dec 2019 11:52:30 -0800 Subject: [PATCH 268/739] Add docs to centralConfig.enabled --- values.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/values.yaml b/values.yaml index c5e0601bc2..0fca42dfef 100644 --- a/values.yaml +++ b/values.yaml @@ -493,6 +493,10 @@ connectInject: # Requires Consul >= v1.5 and consul-k8s >= v0.8.1. centralConfig: + # enabled controls whether central config is enabled on all servers and clients. + # See https://www.consul.io/docs/agent/options.html#enable_central_service_config. + # If changing this after installation, servers and clients must be restarted + # for the change to take effect. enabled: true # defaultProtocol allows you to specify a convenience default protocol if From a1b3c768d2e5df8b5e8026c8de13c3f640df01c4 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 5 Dec 2019 16:44:13 -0800 Subject: [PATCH 269/739] Update values docs to match website --- values.yaml | 72 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/values.yaml b/values.yaml index 16f41ee67f..b7bee2742f 100644 --- a/values.yaml +++ b/values.yaml @@ -1,55 +1,75 @@ # Available parameters and their default values for the Consul chart. +# global holds values that affect multiple components of the chart. global: - # enabled is the master enabled switch. Setting this to true or false - # will enable or disable all the components within this chart by default. - # Each component can be overridden using the component-specific "enabled" - # value. + # enabled is the master enabled/disabled setting. + # If true, servers, clients, Consul DNS and the Consul UI will be enabled. + # Each component can override this default via its component-specific + # "enabled" config. + # If false, no components will be installed by default and per-component + # opt-in is required, such as by setting `server.enabled` to true. enabled: true - # Domain to register the Consul DNS server to listen for. + # domain is the domain Consul will answer DNS queries for + # (see https://www.consul.io/docs/agent/options.html#_domain) and the domain + # services synced from Consul into Kubernetes will have, + # e.g. `service-name.service.consul`. domain: consul - # Image is the name (and tag) of the Consul Docker image for clients and - # servers below. This can be overridden per component. + # image is the name (and tag) of the Consul Docker image for clients and + # servers. This can be overridden per component. + # This should be pinned to a specific version tag, otherwise you may + # inadvertently upgrade your Consul version. # # Examples: + # # Consul 1.5.0 # image: "consul:1.5.0" - # image: "hashicorp/consul-enterprise:1.5.0-ent" # Enterprise Consul image + # # Consul Enterprise 1.5.0 + # image: "hashicorp/consul-enterprise:1.5.0-ent" image: "consul:1.6.2" # imageK8S is the name (and tag) of the consul-k8s Docker image that - # is used for functionality such as the catalog sync. This can be overridden - # per component below. + # is used for functionality such as catalog sync. This can be overridden + # per component. # Note: support for the catalog sync's liveness and readiness probes was added - # to consul-k8s v0.6.0. If using an older consul-k8s version, you may need to + # to consul-k8s 0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. imageK8S: "hashicorp/consul-k8s:0.9.4" - # Datacenter is the name of the datacenter that the agents should register - # as. This shouldn't be changed once the Consul cluster is up and running + # datacenter is the name of the datacenter that the agents should register + # as. This can't be changed once the Consul cluster is up and running # since Consul doesn't support an automatic way to change this value - # currently: https://github.com/hashicorp/consul/issues/1858 + # currently: https://github.com/hashicorp/consul/issues/1858. datacenter: dc1 - # enablePodSecurityPolicies is a boolean flag that controls whether pod - # security policies are created for the consul components created by this - # chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + # enablePodSecurityPolicies controls whether pod + # security policies are created for the Consul components created by this + # chart. See https://kubernetes.io/docs/concepts/policy/pod-security-policy/. enablePodSecurityPolicies: false - # Gossip encryption key. To enable gossip encryption, provide the name of - # a Kubernetes secret that contains a gossip key. You can create a gossip - # key with the "consul keygen" command. - # See https://www.consul.io/docs/commands/keygen.html + # gossipEncryption configures which Kubernetes secret to retrieve Consul's + # gossip encryption key from (see https://www.consul.io/docs/agent/options.html#_encrypt). + # If secretName or secretKey are not set, gossip encryption will not be enabled. + # The secret must be in the same namespace that Consul is installed into. + # + # The secret can be created by running: + # kubectl create secret generic consul-gossip-encryption-key \ + # --from-literal=key=$(consul keygen)`. + # + # In this case, secretName would be "consul-gossip-encryption-key" and + # secretKey would be "key". gossipEncryption: - secretName: null - secretKey: null + # secretName is the name of the Kubernetes secret that holds the gossip + # encryption key. The secret must be in the same namespace that Consul is installed into. + secretName: "" + # secretKey is the key within the Kubernetes secret that holds the gossip + # encryption key. + secretKey: "" # bootstrapACLs will automatically create and assign ACL tokens within - # the Consul cluster. This currently requires enabling both servers and - # clients within Kubernetes. Additionally requires Consul v1.4+ and - # consul-k8s v0.8.0+. + # the Consul cluster. This requires servers to be running inside Kubernetes. + # Additionally requires Consul >= 1.4 and consul-k8s >= 0.8.0. bootstrapACLs: false # Server, when enabled, configures a server cluster to run. This should From cd15aaf5aa3e3133ada2ff8d314eebd072910c8e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 10:39:39 -0800 Subject: [PATCH 270/739] Add pod name as metadata to client nodes --- templates/client-daemonset.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index ce05a3dea7..02bfa5eb6e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -126,6 +126,7 @@ spec: -advertise="${ADVERTISE_IP}" \ -bind=0.0.0.0 \ -client=0.0.0.0 \ + -node-meta=pod-name:${HOSTNAME} \ {{- if .Values.client.grpc }} -hcl="ports { grpc = 8502 }" \ {{- end }} From f4b787e40a7234c5d27489905535205dbc917088 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 9 Dec 2019 16:47:02 -0800 Subject: [PATCH 271/739] Support global.name There was a previously undocumented setting `fullnameOverride` that would allow controlling the prefix added to each resource. There were some places where this wasn't being used. Specifically in our clusterrole's and when running server-acl-init. This change fixes those locations and utilizes a new flag in server-acl-init that will respect the override. It also adds a new value: `global.name` and documents this value. This value is the same as the `fullnameOverride` value, but it lives under the global key which fits with the rest of our config management philosophy (i.e. config that affects the whole chart lives under the global key). --- templates/_helpers.tpl | 6 ++++-- templates/client-clusterrole.yaml | 2 +- templates/client-daemonset.yaml | 2 +- templates/client-snapshot-agent-clusterrole.yaml | 2 +- templates/client-snapshot-agent-deployment.yaml | 4 ++-- templates/connect-inject-deployment.yaml | 2 +- templates/enterprise-license-clusterrole.yaml | 2 +- templates/enterprise-license.yaml | 4 ++-- templates/mesh-gateway-clusterrole.yaml | 2 +- templates/mesh-gateway-deployment.yaml | 4 ++-- templates/server-acl-init-job.yaml | 3 ++- templates/sync-catalog-clusterrole.yaml | 2 +- templates/sync-catalog-deployment.yaml | 4 ++-- values.yaml | 4 ++++ 14 files changed, 25 insertions(+), 18 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 7333b4ab01..fe11cdfee8 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -1,12 +1,14 @@ {{/* 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. +this (by the DNS naming spec). Supports the legacy fullnameOverride setting +as well as the global.name setting. */}} {{- define "consul.fullname" -}} {{- if .Values.fullnameOverride -}} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else if .Values.global.name -}} +{{- .Values.global.name | trunc 63 | trimSuffix "-" -}} {{- else -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index bb330147ee..f42afc9b20 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -23,7 +23,7 @@ rules: resources: - secrets resourceNames: - - {{ .Release.Name }}-consul-client-acl-token + - {{ template "consul.fullname" . }}-client-acl-token verbs: - get {{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index ce05a3dea7..dbb3221d63 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -228,7 +228,7 @@ spec: - "-ec" - | consul-k8s acl-init \ - -secret-name="{{ .Release.Name }}-consul-client-acl-token" \ + -secret-name="{{ template "consul.fullname" . }}-client-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ -init-type="client" volumeMounts: diff --git a/templates/client-snapshot-agent-clusterrole.yaml b/templates/client-snapshot-agent-clusterrole.yaml index c4411c8254..0430b3e925 100644 --- a/templates/client-snapshot-agent-clusterrole.yaml +++ b/templates/client-snapshot-agent-clusterrole.yaml @@ -27,7 +27,7 @@ rules: resources: - secrets resourceNames: - - {{ .Release.Name }}-consul-client-snapshot-agent-acl-token + - {{ template "consul.fullname" . }}-client-snapshot-agent-acl-token verbs: - get {{- end }} diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index 14170c2523..2493db8b5c 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -65,7 +65,7 @@ spec: - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-consul-client-snapshot-agent-acl-token" + name: "{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" key: "token" {{- end}} command: @@ -101,7 +101,7 @@ spec: - "-ec" - | consul-k8s acl-init \ - -secret-name="{{ .Release.Name }}-consul-client-snapshot-agent-acl-token" \ + -secret-name="{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" volumeMounts: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index aed7e28518..b1485dad52 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -57,7 +57,7 @@ spec: {{- if .Values.connectInject.overrideAuthMethodName }} -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ {{ else if .Values.global.bootstrapACLs }} - -acl-auth-method="{{ .Release.Name }}-consul-k8s-auth-method" \ + -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} -enable-central-config=true \ diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-clusterrole.yaml index 6d2bb86ed3..69ece07435 100644 --- a/templates/enterprise-license-clusterrole.yaml +++ b/templates/enterprise-license-clusterrole.yaml @@ -16,7 +16,7 @@ rules: resources: - secrets resourceNames: - - {{ .Release.Name }}-consul-enterprise-license-acl-token + - {{ template "consul.fullname" . }}-enterprise-license-acl-token verbs: - get {{- end }} diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license.yaml index 5bb2fcf4c5..91bd1678b3 100644 --- a/templates/enterprise-license.yaml +++ b/templates/enterprise-license.yaml @@ -48,7 +48,7 @@ spec: - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-consul-enterprise-license-acl-token" + name: "{{ template "consul.fullname" . }}-enterprise-license-acl-token" key: "token" {{- end}} command: @@ -65,7 +65,7 @@ spec: - "-ec" - | consul-k8s acl-init \ - -secret-name="{{ .Release.Name }}-consul-enterprise-license-acl-token" \ + -secret-name="{{ template "consul.fullname" . }}-enterprise-license-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" {{- end }} diff --git a/templates/mesh-gateway-clusterrole.yaml b/templates/mesh-gateway-clusterrole.yaml index 5279f7af9f..33f4dad139 100644 --- a/templates/mesh-gateway-clusterrole.yaml +++ b/templates/mesh-gateway-clusterrole.yaml @@ -24,7 +24,7 @@ rules: resources: - secrets resourceNames: - - {{ .Release.Name }}-consul-mesh-gateway-acl-token + - {{ template "consul.fullname" . }}-mesh-gateway-acl-token verbs: - get {{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index adc6552123..7a907f4bc1 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -78,7 +78,7 @@ spec: - "-ec" - | consul-k8s acl-init \ - -secret-name="{{ .Release.Name }}-consul-mesh-gateway-acl-token" \ + -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" {{- end }} @@ -111,7 +111,7 @@ spec: - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-consul-mesh-gateway-acl-token" + name: "{{ template "consul.fullname" . }}-mesh-gateway-acl-token" key: "token" {{- end}} command: diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 279ee71362..710313a425 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -45,7 +45,8 @@ spec: - "-ec" - | consul-k8s server-acl-init \ - -release-name={{ .Release.Name }} \ + -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \ + -resource-prefix={{ template "consul.fullname" . }} \ -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ diff --git a/templates/sync-catalog-clusterrole.yaml b/templates/sync-catalog-clusterrole.yaml index 9366c04b5e..fe0ed62a18 100644 --- a/templates/sync-catalog-clusterrole.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -34,7 +34,7 @@ rules: resources: - secrets resourceNames: - - {{ .Release.Name }}-consul-catalog-sync-acl-token + - {{ template "consul.fullname" . }}-catalog-sync-acl-token verbs: - get {{- end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index ad57a0ef03..080f61c498 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -52,7 +52,7 @@ spec: - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: - name: "{{ .Release.Name }}-consul-catalog-sync-acl-token" + name: "{{ template "consul.fullname" . }}-catalog-sync-acl-token" key: "token" {{- end}} command: @@ -126,7 +126,7 @@ spec: - "-ec" - | consul-k8s acl-init \ - -secret-name="{{ .Release.Name }}-consul-catalog-sync-acl-token" \ + -secret-name="{{ template "consul.fullname" . }}-catalog-sync-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" {{- end }} diff --git a/values.yaml b/values.yaml index b7f1c51993..62dfdb6e7f 100644 --- a/values.yaml +++ b/values.yaml @@ -10,6 +10,10 @@ global: # opt-in is required, such as by setting `server.enabled` to true. enabled: true + # name sets the prefix used for all resources in the helm chart. + # If not set, the prefix will be "-consul". + name: null + # domain is the domain Consul will answer DNS queries for # (see https://www.consul.io/docs/agent/options.html#_domain) and the domain # services synced from Consul into Kubernetes will have, From ec0a63e1cc8fb7d7087e4898b9d9af0c8e48d611 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 09:08:54 -0800 Subject: [PATCH 272/739] Add tests for consul.fullname helper --- test/unit/helpers.bats | 102 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 test/unit/helpers.bats diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats new file mode 100644 index 0000000000..614e3fcbe5 --- /dev/null +++ b/test/unit/helpers.bats @@ -0,0 +1,102 @@ +#!/usr/bin/env bats +# This file tests the helpers in _helpers.tpl. + +load _helpers + +#-------------------------------------------------------------------- +# consul.fullname +# These tests use test-runner.yaml to test the consul.fullname helper +# since we need an existing template that calls the consul.fullname helper. + +@test "helper/consul.fullname: defaults to release-name-consul" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-test" ] +} + +@test "helper/consul.fullname: fullnameOverride overrides the name" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set fullnameOverride=override \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "override-test" ] +} + +@test "helper/consul.fullname: fullnameOverride is truncated to 63 chars" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set fullnameOverride=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk-test" ] +} + +@test "helper/consul.fullname: fullnameOverride has trailing '-' trimmed" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set fullnameOverride=override- \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "override-test" ] +} + +@test "helper/consul.fullname: global.name overrides the name" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set global.name=override \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "override-test" ] +} + +@test "helper/consul.fullname: global.name is truncated to 63 chars" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set global.name=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk-test" ] +} + +@test "helper/consul.fullname: global.name has trailing '-' trimmed" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set global.name=override- \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "override-test" ] +} + +@test "helper/consul.fullname: nameOverride is supported" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set nameOverride=override \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-override-test" ] +} + +# This test ensures that we use {{ template "consul.fullname" }} everywhere instead of +# {{ .Release.Name }} because that's required in order to support the name +# override settings fullnameOverride and global.name. In some cases, we need to +# use .Release.Name. In those cases, add your exception to this list. +# +# If this test fails, you're likely using {{ .Release.Name }} where you should +# be using {{ template "consul.fullname" }} +@test "helper/consul.fullname: used everywhere" { + cd `chart_dir` + # Grep for uses of .Release.Name that aren't using it as a label. + local actual=$(grep -r '{{ .Release.Name }}' templates/*.yaml | grep -v 'release: ' | tee /dev/stderr ) + [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] +} From 82b0ff5243da6fe7473d31933878a0fae93aaaf6 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 09:24:23 -0800 Subject: [PATCH 273/739] Bump consul-k8s version to 0.10.1. --- values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values.yaml b/values.yaml index 62dfdb6e7f..28f385e366 100644 --- a/values.yaml +++ b/values.yaml @@ -38,7 +38,7 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s 0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - # If using mesh gateways and bootstrapACLs then must be >= 0.9.0. + # If using bootstrapACLs then must be >= 0.10.1. imageK8S: "hashicorp/consul-k8s:0.9.5" # datacenter is the name of the datacenter that the agents should register @@ -73,7 +73,7 @@ global: # bootstrapACLs will automatically create and assign ACL tokens within # the Consul cluster. This requires servers to be running inside Kubernetes. - # Additionally requires Consul >= 1.4 and consul-k8s >= 0.8.0. + # Additionally requires Consul >= 1.4 and consul-k8s >= 0.10.1. bootstrapACLs: false # Server, when enabled, configures a server cluster to run. This should From dc2027724658fb1cb2a59c74d421d990fd82d7d0 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 10:00:30 -0800 Subject: [PATCH 274/739] Add missing component label to statefulset --- templates/server-statefulset.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 21e978f104..93f33927e2 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -10,6 +10,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + component: server spec: serviceName: {{ template "consul.fullname" . }}-server podManagementPolicy: Parallel From 53548de05bbe0155d1009fe9614624039e957f7c Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 11 Dec 2019 14:54:27 -0800 Subject: [PATCH 275/739] Add -consul-k8s-image flag to injector --- templates/connect-inject-deployment.yaml | 1 + values.yaml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index b1485dad52..c0d701a536 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -53,6 +53,7 @@ spec: {{ if .Values.connectInject.imageEnvoy -}} -envoy-image="{{ .Values.connectInject.imageEnvoy }}" \ {{ end -}} + -consul-k8s-image="{{ default .Values.global.imageK8S .Values.connectInject.image }}" \ -listen=:8080 \ {{- if .Values.connectInject.overrideAuthMethodName }} -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ diff --git a/values.yaml b/values.yaml index 28f385e366..7ebaebb324 100644 --- a/values.yaml +++ b/values.yaml @@ -39,7 +39,8 @@ global: # to consul-k8s 0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. # If using bootstrapACLs then must be >= 0.10.1. - imageK8S: "hashicorp/consul-k8s:0.9.5" + # If using connect inject then must be >= 0.10.1. + imageK8S: "hashicorp/consul-k8s:0.10.1" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running @@ -446,6 +447,7 @@ syncCatalog: connectInject: # True if you want to enable connect injection. Set to "-" to inherit from # global.enabled. + # Requires consul-k8s >= 0.10.1. enabled: false image: null # image for consul-k8s that contains the injector default: false # true will inject by default, otherwise requires annotation From 83bcd67d14b8760d34e72ba8ea35445a8707e3c2 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 13:21:08 -0800 Subject: [PATCH 276/739] Update docs to indicate hostPath is not needed --- templates/client-daemonset.yaml | 4 ---- values.yaml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index dbb3221d63..68a272c05e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -55,10 +55,6 @@ spec: dnsPolicy: {{ .Values.client.dnsPolicy }} {{- end }} - # Consul clients require a directory for data. - # We use a hostPath so that if a Pod is restarted it will retain its - # service and checks registrations. This is important for Consul Connect - # because each Connect Pod registers with the local Consul client. volumes: - name: data {{- if .Values.client.dataDirectoryHostPath }} diff --git a/values.yaml b/values.yaml index 7ebaebb324..e3f93caecc 100644 --- a/values.yaml +++ b/values.yaml @@ -196,10 +196,6 @@ client: # to use as the Consul client data directory. # If set to the empty string or null, the Consul agent will store its data # in the Pod's local filesystem (which will be lost if the Pod is deleted). - # If using Consul Connect, this directory must be set. Otherwise when the Consul - # agent Pod is deleted, e.g. during an upgrade, all the Connect-injected Pods - # on that node will be de-registered and will need to be restarted to be - # re-registered. # Security Warning: If setting this, Pod Security Policies *must* be enabled on your cluster # and in this Helm chart (via the global.enablePodSecurityPolicies setting) # to prevent other Pods from mounting the same host path and gaining From ff6c940a0e80ad19f6f2becb6408aa2c766ef039 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 13:24:22 -0800 Subject: [PATCH 277/739] Update changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e15a4d4c0..cd66fc3d29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ IMPROVEMENTS: + * Use latest version of consul-k8s ([0.10.1](https://github.com/hashicorp/consul-k8s/blob/master/CHANGELOG.md#0101-december-17-2019)). + This version fixes a Connect [bug](https://github.com/hashicorp/consul-k8s/issues/161) + where service instances on a node would be deregistered when the Consul + client pod for that node restarted. + + +BREAKING CHANGES: + * `connectInject.centralConfig` defaults to `true` now instead of `false`. This is to make it easier to configure Connect via `service-defaults` and other routing config [[GH-302](https://github.com/hashicorp/consul-helm/pull/302)]. @@ -10,6 +18,10 @@ IMPROVEMENTS: If you wish to disable central config, set `connectInject.centralConfig` to false in your local values file. NOTE: If `connectInject.enabled` is false, then central config is not enabled so this change will not affect you. + + * Connect Inject: If using Connect Inject, you must also upgrade your `consul-k8s` version + to a version >= 0.10.1. A new flag is being passed in to `consul-k8s` which is not + supported in earlier versions. ## 0.14.0 (Dec 10, 2019) @@ -21,6 +33,7 @@ IMPROVEMENTS: e.g. during a Consul version upgrade, it does not lose its Connect service registrations. In the next version, we plan to have services automatically re-register which will remove the need for this. [[GH-298](https://github.com/hashicorp/consul-helm/pull/298)] + (**Update:** 0.15.0 uses a version of consul-k8s that fixes this bug and so hostPath is longer necessary) **Security Warning:** If using this setting, Pod Security Policies *must* be enabled on your cluster and in this Helm chart (via the `global.enablePodSecurityPolicies` setting) From c9d1bc5de6bfe35fa31c548cf89ef15b898dae89 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Dec 2019 15:42:37 -0800 Subject: [PATCH 278/739] Release 0.15.0 --- CHANGELOG.md | 16 +++++++++------- Chart.yaml | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd66fc3d29..e8c721079f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,6 @@ ## Unreleased -IMPROVEMENTS: - - * Use latest version of consul-k8s ([0.10.1](https://github.com/hashicorp/consul-k8s/blob/master/CHANGELOG.md#0101-december-17-2019)). - This version fixes a Connect [bug](https://github.com/hashicorp/consul-k8s/issues/161) - where service instances on a node would be deregistered when the Consul - client pod for that node restarted. - +## 0.15.0 (Dec 17, 2019) BREAKING CHANGES: @@ -23,6 +17,14 @@ BREAKING CHANGES: to a version >= 0.10.1. A new flag is being passed in to `consul-k8s` which is not supported in earlier versions. +BUG FIXES: + * Fix bug with `fullnameOverride` and add new `global.name` setting for changing + the default prefix for resources. [[GH-286](https://github.com/hashicorp/consul-helm/issues/286)] + + * Connect Inject: Fix critical bug where Connect-registered services instances would be de-registered + when the Consul client on the same node was restarted. This fix adds a new + sidecar that ensures the service instance is always registered. [[GH-314](https://github.com/hashicorp/consul-helm/pull/314)] + ## 0.14.0 (Dec 10, 2019) IMPROVEMENTS: diff --git a/Chart.yaml b/Chart.yaml index 6fb906e8d0..a48200cace 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.14.0 +version: 0.15.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From c57aceca2dfc3a8cbb583c282d1c27771f0617a8 Mon Sep 17 00:00:00 2001 From: tehmoon Date: Wed, 1 Jan 2020 20:58:29 -0500 Subject: [PATCH 279/739] Update test-runner.yaml (#320) --- templates/tests/test-runner.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 2ea4d795d6..46860cd7a3 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -3,6 +3,7 @@ apiVersion: v1 kind: Pod metadata: name: "{{ template "consul.fullname" . }}-test" + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} From 2dfe24d35884329c2022b574cb190d6d3dca660a Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 2 Jan 2020 08:52:54 -0600 Subject: [PATCH 280/739] Add -job to filename to match convention --- ...icense.yaml => enterprise-license-job.yaml} | 0 ...icense.bats => enterprise-license-job.bats} | 18 +++++++++--------- test/unit/server-statefulset.bats | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) rename templates/{enterprise-license.yaml => enterprise-license-job.yaml} (100%) rename test/unit/{enterprise-license.bats => enterprise-license-job.bats} (88%) diff --git a/templates/enterprise-license.yaml b/templates/enterprise-license-job.yaml similarity index 100% rename from templates/enterprise-license.yaml rename to templates/enterprise-license-job.yaml diff --git a/test/unit/enterprise-license.bats b/test/unit/enterprise-license-job.bats similarity index 88% rename from test/unit/enterprise-license.bats rename to test/unit/enterprise-license-job.bats index 5071f238e9..8e2dc61387 100644 --- a/test/unit/enterprise-license.bats +++ b/test/unit/enterprise-license-job.bats @@ -5,7 +5,7 @@ load _helpers @test "server/EnterpriseLicense: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -14,7 +14,7 @@ load _helpers @test "server/EnterpriseLicense: disabled when servers are disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ @@ -26,7 +26,7 @@ load _helpers @test "server/EnterpriseLicense: disabled when secretName is missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -36,7 +36,7 @@ load _helpers @test "server/EnterpriseLicense: disabled when secretKey is missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -46,7 +46,7 @@ load _helpers @test "server/EnterpriseLicense: enabled when secretName and secretKey is provided" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | @@ -60,7 +60,7 @@ load _helpers @test "server/EnterpriseLicense: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.bootstrapACLs=true' \ @@ -72,7 +72,7 @@ load _helpers @test "server/EnterpriseLicense: init container is created when global.bootstrapACLs=true" { cd `chart_dir` local object=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.bootstrapACLs=true' \ @@ -91,7 +91,7 @@ load _helpers @test "server/EnterpriseLicense: no service account specified when global.bootstrapACLS=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | @@ -102,7 +102,7 @@ load _helpers @test "server/EnterpriseLicense: service account specified when global.bootstrapACLS=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.bootstrapACLs=true' \ diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index f98979911c..d5865e1a80 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -383,7 +383,7 @@ load _helpers @test "server/StatefulSet: gossip encryption disabled in server StatefulSet when servers are disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license.yaml \ + -x templates/enterprise-license-job.yaml \ --set 'server.enabled=false' \ --set 'global.gossipEncryption.secretName=foo' \ --set 'global.gossipEncryption.secretKey=bar' \ From 5eb9343358dbcdc765535aed146e5b926f146c32 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 2 Jan 2020 10:08:37 -0600 Subject: [PATCH 281/739] Remove test that didn't make sense This test was checking for config within the server statefulset when servers were disabled. This didn't make sense because when servers are disable the statefulset isn't rendered at all. --- test/unit/server-statefulset.bats | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index d5865e1a80..79a686dd34 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -380,18 +380,6 @@ load _helpers [ "${actual}" = "" ] } -@test "server/StatefulSet: gossip encryption disabled in server StatefulSet when servers are disabled" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-job.yaml \ - --set 'server.enabled=false' \ - --set 'global.gossipEncryption.secretName=foo' \ - --set 'global.gossipEncryption.secretKey=bar' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - @test "server/StatefulSet: gossip encryption disabled in server StatefulSet when secretName is missing" { cd `chart_dir` local actual=$(helm template \ From 96282d19fae8e26f6384e42c062fa31930aae1db Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Jan 2020 12:14:05 -0600 Subject: [PATCH 282/739] Remove incorrect comment on RunAsAny RunAsAny means "No default provided. Allows any runAsUser to be specified.", it does not mean that the container must run as non-root. That rule is MustRunAsNonRoot. --- templates/client-podsecuritypolicy.yaml | 1 - templates/client-snapshot-agent-podsecuritypolicy.yaml | 1 - templates/connect-inject-podsecuritypolicy.yaml | 1 - templates/mesh-gateway-podsecuritypolicy.yaml | 1 - templates/sync-catalog-podsecuritypolicy.yaml | 1 - 5 files changed, 5 deletions(-) diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 553e44befe..924bff1d00 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -41,7 +41,6 @@ spec: hostIPC: false hostPID: false runAsUser: - # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: rule: 'RunAsAny' diff --git a/templates/client-snapshot-agent-podsecuritypolicy.yaml b/templates/client-snapshot-agent-podsecuritypolicy.yaml index 88513a484c..a84fa38ff2 100644 --- a/templates/client-snapshot-agent-podsecuritypolicy.yaml +++ b/templates/client-snapshot-agent-podsecuritypolicy.yaml @@ -28,7 +28,6 @@ spec: hostIPC: false hostPID: false runAsUser: - # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: rule: 'RunAsAny' diff --git a/templates/connect-inject-podsecuritypolicy.yaml b/templates/connect-inject-podsecuritypolicy.yaml index 571c609d68..aace192dc8 100644 --- a/templates/connect-inject-podsecuritypolicy.yaml +++ b/templates/connect-inject-podsecuritypolicy.yaml @@ -27,7 +27,6 @@ spec: hostIPC: false hostPID: false runAsUser: - # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: rule: 'RunAsAny' diff --git a/templates/mesh-gateway-podsecuritypolicy.yaml b/templates/mesh-gateway-podsecuritypolicy.yaml index ced5735925..947d513d84 100644 --- a/templates/mesh-gateway-podsecuritypolicy.yaml +++ b/templates/mesh-gateway-podsecuritypolicy.yaml @@ -28,7 +28,6 @@ spec: hostIPC: false hostPID: false runAsUser: - # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: rule: 'RunAsAny' diff --git a/templates/sync-catalog-podsecuritypolicy.yaml b/templates/sync-catalog-podsecuritypolicy.yaml index 93190d80a4..946a3a8bfa 100644 --- a/templates/sync-catalog-podsecuritypolicy.yaml +++ b/templates/sync-catalog-podsecuritypolicy.yaml @@ -27,7 +27,6 @@ spec: hostIPC: false hostPID: false runAsUser: - # Require the container to run without root privileges. rule: 'RunAsAny' seLinux: rule: 'RunAsAny' From 6f9c023b97fadd52a22b443edfba918771c672fa Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Jan 2020 17:02:21 -0600 Subject: [PATCH 283/739] Add PodSecurityPolicies for server-acl-init --- .../server-acl-init-cleanup-clusterrole.yaml | 8 ++++ ...er-acl-init-cleanup-podsecuritypolicy.yaml | 37 +++++++++++++++++++ templates/server-acl-init-clusterrole.yaml | 8 ++++ .../server-acl-init-podsecuritypolicy.yaml | 37 +++++++++++++++++++ .../server-acl-init-cleanup-clusterrole.bats | 14 +++++++ ...er-acl-init-cleanup-podsecuritypolicy.bats | 34 +++++++++++++++++ test/unit/server-acl-init-clusterrole.bats | 28 ++++++++++++++ .../server-acl-init-podsecuritypolicy.bats | 34 +++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 templates/server-acl-init-cleanup-podsecuritypolicy.yaml create mode 100644 templates/server-acl-init-podsecuritypolicy.yaml create mode 100644 test/unit/server-acl-init-cleanup-podsecuritypolicy.bats create mode 100644 test/unit/server-acl-init-podsecuritypolicy.bats diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index 20509ac694..d70db13c31 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -13,5 +13,13 @@ rules: - apiGroups: ["batch"] resources: ["jobs"] verbs: ["get", "delete"] +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-server-acl-init-cleanup + verbs: + - use +{{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml new file mode 100644 index 0000000000..300ff20f23 --- /dev/null +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -0,0 +1,37 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false + {{- end }} + {{- end }} + {{- end }} diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 627a2f8592..15c14ba724 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -38,5 +38,13 @@ rules: verbs: - get {{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-server-acl-init + verbs: + - use +{{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-podsecuritypolicy.yaml b/templates/server-acl-init-podsecuritypolicy.yaml new file mode 100644 index 0000000000..d39e06f344 --- /dev/null +++ b/templates/server-acl-init-podsecuritypolicy.yaml @@ -0,0 +1,37 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.bootstrapACLs }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false + {{- end }} + {{- end }} + {{- end }} diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index f6852515de..badd1a4e68 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -42,3 +42,17 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "serverACLInitCleanup/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats new file mode 100644 index 0000000000..a19bff5146 --- /dev/null +++ b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats @@ -0,0 +1,34 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInitCleanup/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/PodSecurityPolicy: disabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInitCleanup/PodSecurityPolicy: enabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index e005af6469..f63f60f0f3 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -42,3 +42,31 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# connectInject.enabled + +@test "serverACLInit/ClusterRole: allows service accounts when connectInject.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resources[0] == "serviceaccounts")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "serverACLInit/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/test/unit/server-acl-init-podsecuritypolicy.bats b/test/unit/server-acl-init-podsecuritypolicy.bats new file mode 100644 index 0000000000..aee0cb5609 --- /dev/null +++ b/test/unit/server-acl-init-podsecuritypolicy.bats @@ -0,0 +1,34 @@ +#!/usr/bin/env bats + +load _helpers + +@test "serverACLInit/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/PodSecurityPolicy: disabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/PodSecurityPolicy: enabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} From 13030c46e6b966fd59bd438c785ea4934fd65450 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Jan 2020 14:26:21 -0600 Subject: [PATCH 284/739] Add PodSecurityPolicy for enterprise license - add podsecuritypolicy for enterprise license job following the pattern for other psps - set same requirements across resources for rendering: servers enabled and enterprise license secret fully specified. The different resources had different requirements before, for example that clients are running or that bootstrapACLs are true - always create a separate service account for the job, even if acls are disabled. This is to match the pattern across the rest of the templates where we always create a separate service account --- templates/enterprise-license-clusterrole.yaml | 14 +++- ...enterprise-license-clusterrolebinding.yaml | 4 -- templates/enterprise-license-job.yaml | 2 - .../enterprise-license-podsecuritypolicy.yaml | 37 ++++++++++ .../enterprise-license-serviceaccount.yaml | 4 -- test/unit/enterprise-license-clusterrole.bats | 55 +++++++++------ ...enterprise-license-clusterrolebinding.bats | 31 +-------- test/unit/enterprise-license-job.bats | 23 ------- .../enterprise-license-podsecuritypolicy.bats | 68 +++++++++++++++++++ .../enterprise-license-serviceaccount.bats | 31 +-------- 10 files changed, 156 insertions(+), 113 deletions(-) create mode 100644 templates/enterprise-license-podsecuritypolicy.yaml create mode 100644 test/unit/enterprise-license-podsecuritypolicy.bats diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-clusterrole.yaml index 69ece07435..e3078a41ad 100644 --- a/templates/enterprise-license-clusterrole.yaml +++ b/templates/enterprise-license-clusterrole.yaml @@ -1,6 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -11,7 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} rules: +{{- if .Values.global.bootstrapACLs }} - apiGroups: [""] resources: - secrets @@ -20,6 +20,16 @@ rules: verbs: - get {{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-enterprise-license + verbs: + - use +{{- end }} +{{- else }} +rules: [] {{- end }} {{- end }} {{- end }} diff --git a/templates/enterprise-license-clusterrolebinding.yaml b/templates/enterprise-license-clusterrolebinding.yaml index 4726cfff0c..6469adc372 100644 --- a/templates/enterprise-license-clusterrolebinding.yaml +++ b/templates/enterprise-license-clusterrolebinding.yaml @@ -1,6 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -21,5 +19,3 @@ subjects: namespace: {{ .Release.Namespace }} {{- end }} {{- end }} -{{- end }} -{{- end }} diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 91bd1678b3..547ca1c733 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -30,9 +30,7 @@ spec: component: license spec: restartPolicy: Never - {{- if .Values.global.bootstrapACLs }} serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license - {{- end }} containers: - name: apply-enterprise-license image: "{{ default .Values.global.image .Values.server.image }}" diff --git a/templates/enterprise-license-podsecuritypolicy.yaml b/templates/enterprise-license-podsecuritypolicy.yaml new file mode 100644 index 0000000000..0898c203a8 --- /dev/null +++ b/templates/enterprise-license-podsecuritypolicy.yaml @@ -0,0 +1,37 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/enterprise-license-serviceaccount.yaml b/templates/enterprise-license-serviceaccount.yaml index 5d7d735c05..ccb0f37ef9 100644 --- a/templates/enterprise-license-serviceaccount.yaml +++ b/templates/enterprise-license-serviceaccount.yaml @@ -1,6 +1,4 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: v1 kind: ServiceAccount @@ -14,5 +12,3 @@ metadata: release: {{ .Release.Name }} {{- end }} {{- end }} -{{- end }} -{{- end }} diff --git a/test/unit/enterprise-license-clusterrole.bats b/test/unit/enterprise-license-clusterrole.bats index 5d80c42c26..4f02d3ecb3 100644 --- a/test/unit/enterprise-license-clusterrole.bats +++ b/test/unit/enterprise-license-clusterrole.bats @@ -11,72 +11,87 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled with global.bootstrapACLs=true" { +@test "enterpriseLicense/ClusterRole: disabled with server=false, ent secret defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { +@test "enterpriseLicense/ClusterRole: disabled when ent secretName missing" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'server.enabled=false' \ - --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { +@test "enterpriseLicense/ClusterRole: disabled when ent secretKey missing" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'client.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ - --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled when ent secretName missing" { +@test "enterpriseLicense/ClusterRole: enabled when ent license defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } -@test "enterpriseLicense/ClusterRole: disabled when ent secretKey missing" { +@test "enterpriseLicense/ClusterRole: rules are empty if global.bootstrapACLs and global.enablePodSecurityPolicies are false" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq '.rules | length' | tee /dev/stderr) + [ "${actual}" = "0" ] } -@test "enterpriseLicense/ClusterRole: can be enabled" { +#-------------------------------------------------------------------- +# global.bootstrapACLs + +@test "enterpriseLicense/ClusterRole: allows acl token when global.bootstrapACLs is true" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resourceNames[0] == "release-name-consul-enterprise-license-acl-token")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "enterpriseLicense/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-clusterrole.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] } diff --git a/test/unit/enterprise-license-clusterrolebinding.bats b/test/unit/enterprise-license-clusterrolebinding.bats index 3d15169610..eee9bbf994 100644 --- a/test/unit/enterprise-license-clusterrolebinding.bats +++ b/test/unit/enterprise-license-clusterrolebinding.bats @@ -11,21 +11,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: disabled with global.bootstrapACLs=true" { +@test "enterpriseLicense/ClusterRoleBinding: disabled with server=false, ent secret defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - -@test "enterpriseLicense/ClusterRoleBinding: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ @@ -34,24 +23,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'client.enabled=false' \ - --set 'server.enterpriseLicense.secretName=foo' \ - --set 'server.enterpriseLicense.secretKey=bar' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - @test "enterpriseLicense/ClusterRoleBinding: disabled when ent secretName missing" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -62,18 +37,16 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: can be enabled" { +@test "enterpriseLicense/ClusterRoleBinding: enabled when ent license defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | diff --git a/test/unit/enterprise-license-job.bats b/test/unit/enterprise-license-job.bats index 8e2dc61387..2bb5b963bc 100644 --- a/test/unit/enterprise-license-job.bats +++ b/test/unit/enterprise-license-job.bats @@ -87,26 +87,3 @@ load _helpers yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "server/EnterpriseLicense: no service account specified when global.bootstrapACLS=false" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-job.yaml \ - --set 'server.enterpriseLicense.secretName=foo' \ - --set 'server.enterpriseLicense.secretKey=bar' \ - . | tee /dev/stderr | - yq '.spec.template.spec.serviceAccountName' | tee /dev/stderr) - [ "${actual}" = "null" ] -} - -@test "server/EnterpriseLicense: service account specified when global.bootstrapACLS=true" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-job.yaml \ - --set 'server.enterpriseLicense.secretName=foo' \ - --set 'server.enterpriseLicense.secretKey=bar' \ - --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr | - yq '.spec.template.spec.serviceAccountName | contains("consul-enterprise-license")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} diff --git a/test/unit/enterprise-license-podsecuritypolicy.bats b/test/unit/enterprise-license-podsecuritypolicy.bats new file mode 100644 index 0000000000..25908e4a82 --- /dev/null +++ b/test/unit/enterprise-license-podsecuritypolicy.bats @@ -0,0 +1,68 @@ +#!/usr/bin/env bats + +load _helpers + +@test "enterpriseLicense/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/PodSecurityPolicy: disabled with server=false, ent secret defined" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + --set 'server.enabled=false' \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/PodSecurityPolicy: disabled when ent secretName missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + --set 'server.enterpriseLicense.secretKey=bar' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/PodSecurityPolicy: disabled when ent secretKey missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/PodSecurityPolicy: disabled when enablePodSecurityPolicies=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.enablePodSecurityPolicies=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "enterpriseLicense/PodSecurityPolicy: enabled when ent license defined and enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-podsecuritypolicy.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/enterprise-license-serviceaccount.bats b/test/unit/enterprise-license-serviceaccount.bats index c247419f84..de1970b67c 100644 --- a/test/unit/enterprise-license-serviceaccount.bats +++ b/test/unit/enterprise-license-serviceaccount.bats @@ -11,21 +11,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ServiceAccount: disabled with global.bootstrapACLs=true" { +@test "enterpriseLicense/ServiceAccount: disabled with server=false, ent secret defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - -@test "enterpriseLicense/ServiceAccount: disabled with server=false, global.bootstrapACLs=true, ent secret defined" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ @@ -34,24 +23,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ServiceAccount: disabled with client=false, global.bootstrapACLs=true, ent secret defined" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ - --set 'client.enabled=false' \ - --set 'server.enterpriseLicense.secretName=foo' \ - --set 'server.enterpriseLicense.secretKey=bar' \ - . | tee /dev/stderr | - yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] -} - @test "enterpriseLicense/ServiceAccount: disabled when ent secretName missing" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -62,18 +37,16 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ServiceAccount: can be enabled" { +@test "enterpriseLicense/ServiceAccount: enabled when ent license defined" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | From c979a7f365563486500ccd199c7635d3928c18d1 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 10 Jan 2020 14:47:36 -0800 Subject: [PATCH 285/739] Enable TLS (#313) This commit exposes TLS configuration in the Helm chart and makes the following changes: * Optionally allows you to turn on TLS by setting global.tls.enabled to true. * Exposes the default HTTPS port 8501 on clients and servers if TLS enabled. * Optionally allows you to disable HTTP ports on clients and servers by setting global.tls.httpsOnly to false. * Adds TLS bootstrapping job that generates Consul cluster CA, as well as server and client certificates signed by that CA. * Exposes UI service on port 443 if TLS is enabled. * Client certs are generated in an init container so that we can add HOST_IP as a SAN to enable other clients, e.g. sync-catalog, to talk to it * Update pod security policies to account for HTTPS ports exposed as as hostPort if TLS is enabled * Adds tls-init-cleanup job that deletes certs created by the tls-init job when the Helm chart is deleted. * Enables TLS for Consul Connect, Mesh gateways, Sync Catalog, ACL bootstrapping, and snapshot agent * Support incremental rollout of TLS on an existing cluster Other fixes: * fix graceful termination for the servers (previously terminationGracePeriod was set to 10sec, which wasn't enough times or the servers to terminate). Co-authored-by: Todd Radel --- CHANGELOG.md | 19 ++ templates/client-daemonset.yaml | 104 +++++++-- templates/client-podsecuritypolicy.yaml | 9 + .../client-snapshot-agent-deployment.yaml | 25 ++- templates/connect-inject-deployment.yaml | 29 ++- templates/enterprise-license-job.yaml | 22 +- templates/mesh-gateway-deployment.yaml | 28 ++- templates/server-acl-init-job.yaml | 17 ++ templates/server-service.yaml | 7 + templates/server-statefulset.yaml | 54 ++++- templates/sync-catalog-deployment.yaml | 22 +- templates/tests/test-runner.yaml | 22 +- templates/tls-init-cleanup-clusterrole.yaml | 33 +++ .../tls-init-cleanup-clusterrolebinding.yaml | 22 ++ templates/tls-init-cleanup-job.yaml | 52 +++++ .../tls-init-cleanup-podsecuritypolicy.yaml | 36 ++++ .../tls-init-cleanup-serviceaccount.yaml | 14 ++ templates/tls-init-clusterrole.yaml | 32 +++ templates/tls-init-clusterrolebinding.yaml | 25 +++ templates/tls-init-job.yaml | 82 ++++++++ templates/tls-init-podsecuritypolicy.yaml | 39 ++++ templates/tls-init-serviceaccount.yaml | 17 ++ templates/ui-service.yaml | 7 + test/unit/client-daemonset.bats | 198 +++++++++++++++++- test/unit/client-podsecuritypolicy.bats | 50 +++++ .../client-snapshot-agent-deployment.bats | 42 ++++ test/unit/connect-inject-deployment.bats | 49 +++++ test/unit/enterprise-license-job.bats | 87 ++++++++ test/unit/mesh-gateway-deployment.bats | 25 +++ test/unit/server-acl-init-job.bats | 23 ++ test/unit/server-clusterrole.bats | 14 ++ test/unit/server-service.bats | 45 ++++ test/unit/server-statefulset.bats | 181 ++++++++++++++++ test/unit/sync-catalog-deployment.bats | 20 ++ test/unit/tls-init-cleanup-clusterrole.bats | 67 ++++++ .../tls-init-cleanup-clusterrolebinding.bats | 55 +++++ test/unit/tls-init-cleanup-job.bats | 55 +++++ .../tls-init-cleanup-podsecuritypolicy.bats | 44 ++++ .../unit/tls-init-cleanup-serviceaccount.bats | 55 +++++ test/unit/tls-init-clusterrole.bats | 67 ++++++ test/unit/tls-init-clusterrolebinding.bats | 55 +++++ test/unit/tls-init-job.bats | 77 +++++++ test/unit/tls-init-podsecuritypolicy.bats | 44 ++++ test/unit/tls-init-serviceaccount.bats | 55 +++++ test/unit/ui-service.bats | 45 ++++ values.yaml | 44 +++- 46 files changed, 2074 insertions(+), 40 deletions(-) create mode 100644 templates/tls-init-cleanup-clusterrole.yaml create mode 100644 templates/tls-init-cleanup-clusterrolebinding.yaml create mode 100644 templates/tls-init-cleanup-job.yaml create mode 100644 templates/tls-init-cleanup-podsecuritypolicy.yaml create mode 100644 templates/tls-init-cleanup-serviceaccount.yaml create mode 100644 templates/tls-init-clusterrole.yaml create mode 100644 templates/tls-init-clusterrolebinding.yaml create mode 100644 templates/tls-init-job.yaml create mode 100644 templates/tls-init-podsecuritypolicy.yaml create mode 100644 templates/tls-init-serviceaccount.yaml create mode 100644 test/unit/tls-init-cleanup-clusterrole.bats create mode 100644 test/unit/tls-init-cleanup-clusterrolebinding.bats create mode 100644 test/unit/tls-init-cleanup-job.bats create mode 100644 test/unit/tls-init-cleanup-podsecuritypolicy.bats create mode 100644 test/unit/tls-init-cleanup-serviceaccount.bats create mode 100644 test/unit/tls-init-clusterrole.bats create mode 100644 test/unit/tls-init-clusterrolebinding.bats create mode 100644 test/unit/tls-init-job.bats create mode 100644 test/unit/tls-init-podsecuritypolicy.bats create mode 100644 test/unit/tls-init-serviceaccount.bats diff --git a/CHANGELOG.md b/CHANGELOG.md index e8c721079f..ae080c1941 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ ## Unreleased +IMPROVEMENTS: + + * Optionally allow enabling TLS for Consul communication [[GH-313](https://github.com/hashicorp/consul-helm/pull/313)]. + If `global.tls.enabled` is set to `true`, the Helm chart will generate a CA and necessary certificates and + enable TLS for servers, clients, Connect injector, Mesh gateways, catalog sync, ACL bootstrapping, and snapshot agents. + + Note that this feature is only supported if both servers and clients are running + on Kubernetes. We will have better support for other deployment architectures, + as well as bringing your own CA, in the future. + +BUG FIXES: + + * Fix graceful termination for servers [[GH-313](https://github.com/hashicorp/consul-helm/pull/313)]. + `terminationGracePeriod` is now set to 30 seconds for the servers. The previous setting of 10 seconds + wasn't always enough time for a graceful leave, and in those cases, servers leave the cluster + in a "failed" state. Additionally, clients always set `leave_on_terminate` to `true`. + This replaces the `preStop` hook that was calling `consul leave`. Note that `leave_on_terminate` defaults + to true for clients as of Consul `0.7`, so this change only affects earlier versions. + ## 0.15.0 (Dec 17, 2019) BREAKING CHANGES: diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index a54ce52464..94e96fdf86 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -67,6 +67,19 @@ spec: - name: config configMap: name: {{ template "consul.fullname" . }}-client-config + {{- if .Values.global.tls.enabled }} + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + - name: tls-ca-key + secret: + secretName: {{ template "consul.fullname" . }}-ca-key + - name: tls-client-cert + emptyDir: + # We're using tmpfs here so that + # client certs are not written to disk + medium: "Memory" + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} {{ .type }}: @@ -80,7 +93,6 @@ spec: - name: aclconfig emptyDir: {} {{- end }} - containers: - name: consul image: "{{ default .Values.global.image .Values.client.image }}" @@ -110,6 +122,12 @@ spec: name: {{ .Values.global.gossipEncryption.secretName }} key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://localhost:8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end }} {{- include "consul.extraEnvironmentVars" .Values.client | nindent 12 }} command: - "/bin/sh" @@ -123,8 +141,23 @@ spec: -bind=0.0.0.0 \ -client=0.0.0.0 \ -node-meta=pod-name:${HOSTNAME} \ + -hcl='leave_on_terminate = true' \ + {{- if .Values.global.tls.enabled }} + -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ + -hcl='cert_file = "/consul/tls/client/tls.crt"' \ + -hcl='key_file = "/consul/tls/client/tls.key"' \ + {{- if .Values.global.tls.verify }} + -hcl='verify_incoming_rpc = true' \ + -hcl='verify_outgoing = true' \ + -hcl='verify_server_hostname = true' \ + {{- end }} + -hcl='ports { https = 8501 }' \ + {{- if .Values.global.tls.httpsOnly }} + -hcl='ports { http = -1 }' \ + {{- end }} + {{- end }} {{- if .Values.client.grpc }} - -hcl="ports { grpc = 8502 }" \ + -hcl='ports { grpc = 8502 }' \ {{- end }} -config-dir=/consul/config \ {{- range .Values.client.extraVolumes }} @@ -157,6 +190,14 @@ spec: mountPath: /consul/data - name: config mountPath: /consul/config + {{- if .Values.global.tls.enabled }} + - name: tls-ca-cert + mountPath: /consul/tls/ca + readOnly: true + - name: tls-client-cert + mountPath: /consul/tls/client + readOnly: true + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} readOnly: true @@ -166,17 +207,17 @@ spec: - name: aclconfig mountPath: /consul/aclconfig {{- end }} - lifecycle: - preStop: - exec: - command: - - /bin/sh - - -c - - consul leave ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - containerPort: 8500 hostPort: 8500 name: http + {{- end }} + {{- if .Values.global.tls.enabled }} + - containerPort: 8501 + hostPort: 8501 + name: https + {{- end }} - containerPort: 8502 hostPort: 8502 name: grpc @@ -210,14 +251,21 @@ spec: - "/bin/sh" - "-ec" - | - curl http://127.0.0.1:8500/v1/status/leader 2>/dev/null | \ - grep -E '".+"' + {{- if .Values.global.tls.enabled }} + curl \ + --cacert /consul/tls/ca/tls.crt \ + https://127.0.0.1:8501/v1/status/leader \ + {{- else }} + curl http://127.0.0.1:8500/v1/status/leader \ + {{- end }} + 2>/dev/null | grep -E '".+"' {{- if .Values.client.resources }} resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled) }} initContainers: + {{- if .Values.global.bootstrapACLs }} - name: client-acl-init image: {{ .Values.global.imageK8S }} command: @@ -232,6 +280,38 @@ spec: - name: aclconfig mountPath: /consul/aclconfig {{- end }} + {{- if .Values.global.tls.enabled }} + - name: client-tls-init + image: "{{ default .Values.global.image .Values.client.image }}" + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + command: + - "/bin/sh" + - "-ec" + - | + cd /consul/tls/client + consul tls cert create -client \ + -additional-ipaddress=${HOST_IP} \ + -dc={{ .Values.global.datacenter }} \ + -domain={{ .Values.global.domain }} \ + -ca=/consul/tls/ca/cert/tls.crt \ + -key=/consul/tls/ca/key/tls.key + mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0.pem tls.crt + mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0-key.pem tls.key + volumeMounts: + - name: tls-client-cert + mountPath: /consul/tls/client + - name: tls-ca-cert + mountPath: /consul/tls/ca/cert + readOnly: true + - name: tls-ca-key + mountPath: /consul/tls/ca/key + readOnly: true + {{- end }} + {{- end }} {{- if .Values.client.nodeSelector }} nodeSelector: {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 924bff1d00..9d46a23837 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -28,12 +28,21 @@ spec: {{- end }} hostNetwork: false hostPorts: + {{- if (not (and .Values.global.tls.enabled .Values.global.tls.httpsOnly)) }} # HTTP Port - min: 8500 max: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + # HTTPS port + - min: 8501 + max: 8501 + {{- end }} + {{- if .Values.client.grpc }} # gRPC Port - min: 8502 max: 8502 + {{- end }} {{- if .Values.client.exposeGossipPorts }} - min: 8301 max: 8301 diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index 2493db8b5c..e1d99e14e9 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -34,11 +34,10 @@ spec: {{- end }} terminationGracePeriodSeconds: 10 serviceAccountName: {{ template "consul.fullname" . }}-snapshot-agent - {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} {{- end }} - {{- if (or .Values.global.bootstrapACLs (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} + {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} volumes: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config @@ -52,6 +51,11 @@ spec: - name: aclconfig emptyDir: {} {{- end }} + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} {{- end }} containers: - name: consul-snapshot-agent @@ -61,6 +65,15 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} {{- if .Values.global.bootstrapACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: @@ -79,8 +92,7 @@ spec: {{- if .Values.global.bootstrapACLs}} -config-dir=/consul/aclconfig \ {{- end }} - -http-addr=http://${HOST_IP}:8500 - {{- if (or .Values.global.bootstrapACLs (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} + {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} volumeMounts: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config @@ -91,6 +103,11 @@ spec: - name: aclconfig mountPath: /consul/aclconfig {{- end }} + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} {{- end }} {{- if .Values.global.bootstrapACLs }} initContainers: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index c0d701a536..59581e8c91 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -60,19 +60,22 @@ spec: {{ else if .Values.global.bootstrapACLs }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} + {{- if .Values.global.tls.enabled }} + -consul-ca-cert=/consul/tls/ca/tls.crt \ + {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} -enable-central-config=true \ {{- end }} {{- if (and .Values.connectInject.centralConfig.enabled .Values.connectInject.centralConfig.defaultProtocol) }} -default-protocol="{{ .Values.connectInject.centralConfig.defaultProtocol }}" \ {{- end }} -{{- if .Values.connectInject.certs.secretName }} + {{- if .Values.connectInject.certs.secretName }} -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \ -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} -{{- else }} + {{- else }} -tls-auto=${CONSUL_FULLNAME}-connect-injector-cfg \ -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc -{{- end }} + {{- end }} livenessProbe: httpGet: path: /health/ready @@ -93,16 +96,32 @@ spec: periodSeconds: 2 successThreshold: 1 timeoutSeconds: 5 -{{- if .Values.connectInject.certs.secretName }} + {{- if (or .Values.connectInject.certs.secretName .Values.global.tls.enabled) }} volumeMounts: + {{- if .Values.connectInject.certs.secretName }} - name: certs mountPath: /etc/connect-injector/certs readOnly: true + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + {{- if (or .Values.connectInject.certs.secretName .Values.global.tls.enabled) }} volumes: + {{- if .Values.connectInject.certs.secretName }} - name: certs secret: secretName: {{ .Values.connectInject.certs.secretName }} -{{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + {{- end }} {{- if .Values.connectInject.nodeSelector }} nodeSelector: {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 547ca1c733..910aecbadf 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -31,6 +31,12 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license + {{- if .Values.global.tls.enabled }} + volumes: + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} containers: - name: apply-enterprise-license image: "{{ default .Values.global.image .Values.server.image }}" @@ -41,7 +47,15 @@ spec: name: {{ .Values.server.enterpriseLicense.secretName }} key: {{ .Values.server.enterpriseLicense.secretKey }} - name: CONSUL_HTTP_ADDR + {{- if .Values.global.tls.enabled }} + value: https://{{ template "consul.fullname" . }}-server:8501 + {{- else }} value: http://{{ template "consul.fullname" . }}-server:8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end}} {{- if .Values.global.bootstrapACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: @@ -49,11 +63,17 @@ spec: name: "{{ template "consul.fullname" . }}-enterprise-license-acl-token" key: "token" {{- end}} - command: + command: - "/bin/sh" - "-ec" - | consul license put "${ENTERPRISE_LICENSE}" + {{- if .Values.global.tls.enabled }} + volumeMounts: + - name: tls-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} {{- if .Values.global.bootstrapACLs }} initContainers: - name: ent-license-acl-init diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 7a907f4bc1..b6c7cfa0a1 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -48,6 +48,11 @@ spec: volumes: - name: consul-bin emptyDir: {} + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} {{- if .Values.meshGateway.hostNetwork }} hostNetwork: {{ .Values.meshGateway.hostNetwork }} {{- end }} @@ -92,6 +97,11 @@ spec: volumeMounts: - name: consul-bin mountPath: /consul-bin + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} env: - name: HOST_IP valueFrom: @@ -114,6 +124,19 @@ spec: name: "{{ template "consul.fullname" . }}-mesh-gateway-acl-token" key: "token" {{- end}} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_GRPC_ADDR + value: https://$(HOST_IP):8502 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + - name: CONSUL_GRPC_ADDR + value: $(HOST_IP):8502 + {{- end }} command: # /bin/sh -c is needed so we can use the pod-specific environment # variables. @@ -124,8 +147,6 @@ spec: -mesh-gateway \ -register \ -address="${POD_IP}:{{ .Values.meshGateway.containerPort }}" \ - -http-addr="${HOST_IP}:8500" \ - -grpc-addr="${HOST_IP}:8502" \ {{- if .Values.meshGateway.wanAddress.host }} -wan-address="{{ .Values.meshGateway.wanAddress.host }}:{{ .Values.meshGateway.wanAddress.port }}" \ {{- else if .Values.meshGateway.wanAddress.useNodeName }} @@ -164,7 +185,8 @@ spec: lifecycle: preStop: exec: - command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -http-addr=\"${HOST_IP}:8500\" -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""] + command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""] + {{- if .Values.meshGateway.priorityClassName }} priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} {{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 710313a425..adb7b918d5 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -32,6 +32,12 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init + {{- if .Values.global.tls.enabled }} + volumes: + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} containers: - name: post-install-job image: {{ .Values.global.imageK8S }} @@ -40,6 +46,12 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- if .Values.global.tls.enabled }} + volumeMounts: + - name: tls-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} command: - "/bin/sh" - "-ec" @@ -48,6 +60,11 @@ spec: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \ -resource-prefix={{ template "consul.fullname" . }} \ -k8s-namespace={{ .Release.Namespace }} \ + {{- if .Values.global.tls.enabled }} + -use-https \ + -consul-ca-cert=/consul/tls/ca/tls.crt \ + -consul-tls-server-name=server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }} \ + {{- end }} {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ {{- end }} diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 9a208699f5..4abaf8a25d 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -25,9 +25,16 @@ spec: # since this DNS is also used for join operations. publishNotReadyAddresses: true ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - name: http port: 8500 targetPort: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + port: 8501 + targetPort: 8501 + {{- end }} - name: serflan-tcp protocol: "TCP" port: 8301 diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 93f33927e2..7f448f1822 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -50,7 +50,7 @@ spec: tolerations: {{ tpl .Values.server.tolerations . | nindent 8 | trim }} {{- end }} - terminationGracePeriodSeconds: 10 + terminationGracePeriodSeconds: 30 serviceAccountName: {{ template "consul.fullname" . }}-server securityContext: fsGroup: 1000 @@ -58,6 +58,14 @@ spec: - name: config configMap: name: {{ template "consul.fullname" . }}-server-config + {{- if .Values.global.tls.enabled }} + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + - name: tls-server-cert + secret: + secretName: {{ template "consul.fullname" . }}-server-cert + {{- end }} {{- range .Values.server.extraVolumes }} - name: userconfig-{{ .name }} {{ .type }}: @@ -89,6 +97,12 @@ spec: name: {{ .Values.global.gossipEncryption.secretName }} key: {{ .Values.global.gossipEncryption.secretKey }} {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://localhost:8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end }} {{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }} command: - "/bin/sh" @@ -100,6 +114,20 @@ spec: -advertise="${POD_IP}" \ -bind=0.0.0.0 \ -bootstrap-expect={{ .Values.server.bootstrapExpect }} \ + {{- if .Values.global.tls.enabled }} + -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ + -hcl='cert_file = "/consul/tls/server/tls.crt"' \ + -hcl='key_file = "/consul/tls/server/tls.key"' \ + {{- if .Values.global.tls.verify }} + -hcl='verify_incoming_rpc = true' \ + -hcl='verify_outgoing = true' \ + -hcl='verify_server_hostname = true' \ + {{- end }} + -hcl='ports { https = 8501 }' \ + {{- if .Values.global.tls.httpsOnly }} + -hcl='ports { http = -1 }' \ + {{- end }} + {{- end }} -client=0.0.0.0 \ -config-dir=/consul/config \ {{- range .Values.server.extraVolumes }} @@ -128,6 +156,14 @@ spec: mountPath: /consul/data - name: config mountPath: /consul/config + {{- if .Values.global.tls.enabled }} + - name: tls-ca-cert + mountPath: /consul/tls/ca/ + readOnly: true + - name: tls-server-cert + mountPath: /consul/tls/server + readOnly: true + {{- end }} {{- range .Values.server.extraVolumes }} - name: userconfig-{{ .name }} readOnly: true @@ -141,8 +177,14 @@ spec: - -c - consul leave ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - containerPort: 8500 name: http + {{- end }} + {{- if .Values.global.tls.enabled }} + - containerPort: 8501 + name: https + {{- end }} - containerPort: 8301 name: serflan - containerPort: 8302 @@ -163,8 +205,14 @@ spec: - "/bin/sh" - "-ec" - | - curl http://127.0.0.1:8500/v1/status/leader 2>/dev/null | \ - grep -E '".+"' + {{- if .Values.global.tls.enabled }} + curl \ + --cacert /consul/tls/ca/tls.crt \ + https://127.0.0.1:8501/v1/status/leader \ + {{- else }} + curl http://127.0.0.1:8500/v1/status/leader \ + {{- end }} + 2>/dev/null | grep -E '".+"' failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 3 diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 080f61c498..5ad4d6cbf9 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -29,6 +29,12 @@ spec: "consul.hashicorp.com/connect-inject": "false" spec: serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog + {{- if .Values.global.tls.enabled }} + volumes: + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} containers: - name: consul-sync-catalog image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" @@ -55,12 +61,26 @@ spec: name: "{{ template "consul.fullname" . }}-catalog-sync-acl-token" key: "token" {{- end}} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + volumeMounts: + - name: tls-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} command: - "/bin/sh" - "-ec" - | consul-k8s sync-catalog \ - -http-addr=${HOST_IP}:8500 \ -k8s-default-sync={{ .Values.syncCatalog.default }} \ {{- if (not .Values.syncCatalog.toConsul) }} -to-consul=false \ diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 46860cd7a3..416d0cfd72 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -12,6 +12,12 @@ metadata: annotations: "helm.sh/hook": test-success spec: + {{- if .Values.global.tls.enabled }} + volumes: + - name: tls-ca-cert + secret: + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} containers: - name: consul-test image: "{{ .Values.global.image }}" @@ -20,12 +26,26 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + volumeMounts: + - name: tls-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} command: - "/bin/sh" - "-ec" - | export VALUE="{{ .Release.Name }}" - export CONSUL_HTTP_ADDR="${HOST_IP}:8500" consul kv delete _consul_helm_test consul kv put _consul_helm_test $VALUE [ `consul kv get _consul_helm_test` = "$VALUE" ] diff --git a/templates/tls-init-cleanup-clusterrole.yaml b/templates/tls-init-cleanup-clusterrole.yaml new file mode 100644 index 0000000000..6f6a31542a --- /dev/null +++ b/templates/tls-init-cleanup-clusterrole.yaml @@ -0,0 +1,33 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +rules: +- apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-ca-cert + - {{ template "consul.fullname" . }}-ca-key + - {{ template "consul.fullname" . }}-server-cert + verbs: + - delete +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-tls-init-cleanup +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/tls-init-cleanup-clusterrolebinding.yaml b/templates/tls-init-cleanup-clusterrolebinding.yaml new file mode 100644 index 0000000000..b97efe48d7 --- /dev/null +++ b/templates/tls-init-cleanup-clusterrolebinding.yaml @@ -0,0 +1,22 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-tls-init-cleanup +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/templates/tls-init-cleanup-job.yaml b/templates/tls-init-cleanup-job.yaml new file mode 100644 index 0000000000..7c9156714f --- /dev/null +++ b/templates/tls-init-cleanup-job.yaml @@ -0,0 +1,52 @@ +# tls-init-cleanup job deletes Kubernetes secrets created by tls-init +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: tls-init-cleanup + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-tls-init-cleanup + containers: + - name: tls-init-cleanup + image: "{{ .Values.global.image }}" + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-cert \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-key \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-server-cert \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" +{{- end }} +{{- end }} diff --git a/templates/tls-init-cleanup-podsecuritypolicy.yaml b/templates/tls-init-cleanup-podsecuritypolicy.yaml new file mode 100644 index 0000000000..d58e2bd2da --- /dev/null +++ b/templates/tls-init-cleanup-podsecuritypolicy.yaml @@ -0,0 +1,36 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/templates/tls-init-cleanup-serviceaccount.yaml b/templates/tls-init-cleanup-serviceaccount.yaml new file mode 100644 index 0000000000..b62a005b06 --- /dev/null +++ b/templates/tls-init-cleanup-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- end }} +{{- end }} diff --git a/templates/tls-init-clusterrole.yaml b/templates/tls-init-clusterrole.yaml new file mode 100644 index 0000000000..dfd75eb04a --- /dev/null +++ b/templates/tls-init-clusterrole.yaml @@ -0,0 +1,32 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +rules: +- apiGroups: [""] + resources: + - secrets + verbs: + - create +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-tls-init +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/tls-init-clusterrolebinding.yaml b/templates/tls-init-clusterrolebinding.yaml new file mode 100644 index 0000000000..7ce6801fa2 --- /dev/null +++ b/templates/tls-init-clusterrolebinding.yaml @@ -0,0 +1,25 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-tls-init +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml new file mode 100644 index 0000000000..30c8c02a98 --- /dev/null +++ b/templates/tls-init-job.yaml @@ -0,0 +1,82 @@ +# tls-init job generate Consul cluster CA and certificates for the Consul servers +# and creates Kubernetes secrets for them. +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-tls-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-tls-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: tls-init + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-tls-init + containers: + - name: tls-init + image: "{{ .Values.global.image }}" + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # We're using POST requests below to create secrets via Kubernetes API. + # Note that in the subsequent runs of the job, POST requests will + # return a 409 because these secrets would already exist; + # we are ignoring these response codes. + command: + - "/bin/sh" + - "-ec" + - | + consul tls ca create + consul tls cert create -server \ + -days=730 \ + -additional-dnsname='{{ template "consul.fullname" . }}-server' \ + -additional-dnsname='*.{{ template "consul.fullname" . }}-server' \ + -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}' \ + -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc' \ + {{- range .Values.global.tls.serverAdditionalIPSANs }} + -additional-ipaddress={{ . }} \ + {{- end }} + {{- range .Values.global.tls.serverAdditionalDNSSANs }} + -additional-dnsname={{ . }} \ + {{- end }} + -dc={{ .Values.global.datacenter }} \ + -domain={{ .Values.global.domain }} + curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.domain }}-agent-ca.pem | base64 | tr -d '\n' )\" }}" > /dev/null + curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-key\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.key\": \"$( cat {{ .Values.global.domain }}-agent-ca-key.pem | base64 | tr -d '\n' )\" }}" > /dev/null + curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-server-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"kubernetes.io/tls\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0.pem | base64 | tr -d '\n' )\", \"tls.key\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0-key.pem | base64 | tr -d '\n' )\" } }" > /dev/null +{{- end }} +{{- end }} diff --git a/templates/tls-init-podsecuritypolicy.yaml b/templates/tls-init-podsecuritypolicy.yaml new file mode 100644 index 0000000000..30854bfc53 --- /dev/null +++ b/templates/tls-init-podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-tls-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/templates/tls-init-serviceaccount.yaml b/templates/tls-init-serviceaccount.yaml new file mode 100644 index 0000000000..e59e44efc4 --- /dev/null +++ b/templates/tls-init-serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if .Values.global.tls.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +{{- end }} +{{- end }} diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index fc265d0b35..6f122717e4 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -20,9 +20,16 @@ spec: release: "{{ .Release.Name }}" component: server ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - name: http port: 80 targetPort: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + port: 443 + targetPort: 8501 + {{- end }} {{- if .Values.ui.service.type }} type: {{ .Values.ui.service.type }} {{- end }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 8d29131b5f..438d9a8763 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -418,9 +418,201 @@ load _helpers --set 'global.gossipEncryption.secretName=bar' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[] | select(.name=="consul") | .command | join(" ") | contains("encrypt")' | tee /dev/stderr) + [ "${actual}" == "true" ] +} + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "client/DaemonSet: CA volume present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "client/DaemonSet: client certificate volume present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "tls-client-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "client/DaemonSet: port 8501 is not exposed when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8501)' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "client/DaemonSet: port 8501 is exposed when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8501)' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "client/DaemonSet: port 8500 is still exposed when httpsOnly is not enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8500)' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "client/DaemonSet: port 8500 is not exposed when httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8500)' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "client/DaemonSet: readiness checks are over HTTP TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("http://127.0.0.1:8500")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: readiness checks are over HTTPS when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("https://127.0.0.1:8501")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: readiness checks use CA certificate when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("--cacert /consul/tls/ca/tls.crt")' | tee /dev/stderr) [ "${actual}" = "true" ] } +@test "client/DaemonSet: HTTP port is disabled when global.tls.httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("ports { http = -1 }")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: init container is created when global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "client-tls-init") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: both ACL and TLS init containers are created when global.tls.enabled=true and global.bootstrapACLs=true" { + cd `chart_dir` + local has_acl_init_container=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init") | length > 0' | tee /dev/stderr) + + [ "${has_acl_init_container}" = "true" ] + + local has_tls_init_container=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init") | length > 0' | tee /dev/stderr) + + [ "${has_tls_init_container}" = "true" ] +} + +@test "client/DaemonSet: sets Consul environment variables when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = "https://localhost:8501" ] + + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "client/DaemonSet: sets verify_* flags to true by default when global.tls.enabled" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ")' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | contains("verify_incoming_rpc = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | contains("verify_outgoing = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: doesn't set the verify_* flags by default when global.tls.enabled and global.tls.verify is false" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.verify=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ")' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | contains("verify_incoming_rpc = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] + + actual=$(echo $command | jq -r '. | contains("verify_outgoing = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] + + actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + #-------------------------------------------------------------------- # extraEnvironmentVariables @@ -496,11 +688,7 @@ load _helpers -x templates/client-daemonset.yaml \ --set 'global.bootstrapACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) - - local actual=$(echo $object | - yq -r '.name' | tee /dev/stderr) - [ "${actual}" = "client-acl-init" ] + yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init")' | tee /dev/stderr) local actual=$(echo $object | yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) diff --git a/test/unit/client-podsecuritypolicy.bats b/test/unit/client-podsecuritypolicy.bats index 8fdfc298ab..2622a45e42 100644 --- a/test/unit/client-podsecuritypolicy.bats +++ b/test/unit/client-podsecuritypolicy.bats @@ -32,6 +32,30 @@ load _helpers [ "${actual}" = "true" ] } +@test "client/PodSecurityPolicy: only http and grpc ports are allowed as hostPorts by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -c '.spec.hostPorts' | tee /dev/stderr) + [ "${actual}" = '[{"min":8500,"max":8500},{"min":8502,"max":8502}]' ] +} + +#-------------------------------------------------------------------- +# client.grpc + +@test "client/PodSecurityPolicy: hostPort 8502 is not allowed when client.grpc=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.grpc=false' \ + . | tee /dev/stderr | + yq -c '.spec.hostPorts' | tee /dev/stderr) + [ "${actual}" = '[{"min":8500,"max":8500}]' ] +} + #-------------------------------------------------------------------- # client.exposeGossipPorts @@ -79,3 +103,29 @@ load _helpers yq -r '.spec.allowedHostPaths[0].pathPrefix' | tee /dev/stderr) [ "${actual}" = '/opt/consul' ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "client/PodSecurityPolicy: hostPort 8501 is allowed when global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -c '.spec.hostPorts' | tee /dev/stderr) + [ "${actual}" = '[{"min":8501,"max":8501},{"min":8502,"max":8502}]' ] +} + +@test "client/PodSecurityPolicy: hostPort 8500 is not allowed when global.tls.enabled=true and global.tls.httpsOnly=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq -c '.spec.hostPorts' | tee /dev/stderr) + [ "${actual}" = '[{"min":8501,"max":8501},{"min":8502,"max":8502}]' ] +} diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index a13ae943c3..ca8887f3f2 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -204,3 +204,45 @@ load _helpers yq '.spec.template.spec.nodeSelector | contains("allow")' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "client/SnapshotAgentDeployment: sets TLS env vars when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "client/SnapshotAgentDeployment: populates volumes when global.tls.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: populates container volumeMounts when global.tls.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 8709ae208e..aa748f156e 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -360,3 +360,52 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"override\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "connectInject/Deployment: Adds tls-ca-cert volume when global.tls.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "connectInject/Deployment: Adds both tls-ca-cert and certs volumes when global.tls.enabled is true and connectInject.certs.secretName is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "connectInject/Deployment: Adds tls-ca-cert volumeMounts when global.tls.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "connectInject/Deployment: Adds both tls-ca-cert and certs volumeMounts when global.tls.enabled is true and connectInject.certs.secretName is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'connectInject.certs.secretName=foo' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length' | tee /dev/stderr) + [ "${actual}" = "2" ] +} diff --git a/test/unit/enterprise-license-job.bats b/test/unit/enterprise-license-job.bats index 2bb5b963bc..283dd163f0 100644 --- a/test/unit/enterprise-license-job.bats +++ b/test/unit/enterprise-license-job.bats @@ -87,3 +87,90 @@ load _helpers yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "server/EnterpriseLicense: no volumes when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "server/EnterpriseLicense: volumes present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "server/EnterpriseLicense: no volumes mounted when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "server/EnterpriseLicense: volumes mounted when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "server/EnterpriseLicense: URL is http when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = "http://release-name-consul-server:8500" ] +} + +@test "server/EnterpriseLicense: URL is https when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = "https://release-name-consul-server:8501" ] +} + +@test "server/EnterpriseLicense: CA certificate is specified when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 535dd2f2c9..5461a0d193 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -604,3 +604,28 @@ key2: value2' \ [ "${actual}" = "value" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "meshGateway/Deployment: sets TLS flags when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_GRPC_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8502' ] + + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 682fcc6637..94ad1bd4eb 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -210,3 +210,26 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-create-mesh-gateway-token"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "serverACLInit/Job: sets TLS flags when global.tls.enabled" { + cd `chart_dir` + local command=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | any(contains("-use-https"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-consul-tls-server-name=server.dc1.consul"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-clusterrole.bats b/test/unit/server-clusterrole.bats index 37b37dea93..88f005bc65 100644 --- a/test/unit/server-clusterrole.bats +++ b/test/unit/server-clusterrole.bats @@ -62,3 +62,17 @@ load _helpers yq '.rules' | tee /dev/stderr) [ "${actual}" = "[]" ] } + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "server/ClusterRole: podsecuritypolicies are added when global.enablePodSecurityPolicies is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-clusterrole.yaml \ + --set 'server.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/test/unit/server-service.bats b/test/unit/server-service.bats index 024314983f..d1c180ec4b 100755 --- a/test/unit/server-service.bats +++ b/test/unit/server-service.bats @@ -58,3 +58,48 @@ load _helpers yq -r '.spec.publishNotReadyAddresses' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "server/Service: no HTTPS listener when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "https") | .port' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "server/Service: HTTPS listener set when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "https") | .port' | tee /dev/stderr) + [ "${actual}" == "8501" ] +} + +@test "server/Service: HTTP listener still active when httpsOnly is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "http") | .port' | tee /dev/stderr) + [ "${actual}" == "8500" ] +} + +@test "server/Service: no HTTP listener when httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "http") | .port' | tee /dev/stderr) + [ "${actual}" == "" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 79a686dd34..4f5ade5783 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -459,3 +459,184 @@ load _helpers yq -r '.[3].value' | tee /dev/stderr) [ "${actual}" = "custom_no_proxy" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "server/StatefulSet: CA volume present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: server volume present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "tls-server-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: CA volume mounted when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: server certificate volume mounted when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-server-cert")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: port 8501 is not exposed when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8501)' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "server/StatefulSet: port 8501 is exposed when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8501)' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: port 8500 is still exposed when httpsOnly is not enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8500)' | tee /dev/stderr) + [ "${actual}" != "" ] +} + +@test "server/StatefulSet: port 8500 is not exposed when httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].ports[] | select (.containerPort == 8500)' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "server/StatefulSet: readiness checks are over HTTP when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("http://127.0.0.1:8500")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: readiness checks are over HTTPS when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("https://127.0.0.1:8501")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: CA certificate is specified when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("--cacert /consul/tls/ca/tls.crt")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: HTTP is disabled in agent when httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("ports { http = -1 }")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: sets Consul environment variables when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = "https://localhost:8501" ] + + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "server/StatefulSet: sets verify_* flags to true by default when global.tls.enabled" { + cd `chart_dir` + local command=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ")' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | contains("verify_incoming_rpc = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | contains("verify_outgoing = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: doesn't set the verify_* flags by default when global.tls.enabled and global.tls.verify is false" { + cd `chart_dir` + local command=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.verify=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ")' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | contains("verify_incoming_rpc = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] + + actual=$(echo $command | jq -r '. | contains("verify_outgoing = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] + + actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 306b707444..cce24f84ac 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -395,3 +395,23 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-add-k8s-namespace-suffix"))' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "syncCatalog/Deployment: sets Consul environment variables when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} diff --git a/test/unit/tls-init-cleanup-clusterrole.bats b/test/unit/tls-init-cleanup-clusterrole.bats new file mode 100644 index 0000000000..0357287971 --- /dev/null +++ b/test/unit/tls-init-cleanup-clusterrole.bats @@ -0,0 +1,67 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInitCleanup/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRole: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRole: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRole: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInitCleanup/ClusterRole: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInitCleanup/ClusterRole: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[] | select(.resources==["podsecuritypolicies"]) | .resourceNames[0]' | tee /dev/stderr) + + [ "${actual}" = "release-name-consul-tls-init-cleanup" ] +} diff --git a/test/unit/tls-init-cleanup-clusterrolebinding.bats b/test/unit/tls-init-cleanup-clusterrolebinding.bats new file mode 100644 index 0000000000..d8d414e00c --- /dev/null +++ b/test/unit/tls-init-cleanup-clusterrolebinding.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInitCleanup/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRoleBinding: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRoleBinding: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInitCleanup/ClusterRoleBinding: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ClusterRoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-cleanup-job.bats b/test/unit/tls-init-cleanup-job.bats new file mode 100644 index 0000000000..adf89a8fb1 --- /dev/null +++ b/test/unit/tls-init-cleanup-job.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInitCleanup/Job: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-job.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/Job: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/Job: enabled with global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInitCleanup/Job: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/Job: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-cleanup-podsecuritypolicy.bats b/test/unit/tls-init-cleanup-podsecuritypolicy.bats new file mode 100644 index 0000000000..a5be6d7718 --- /dev/null +++ b/test/unit/tls-init-cleanup-podsecuritypolicy.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInitCleanup/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/PodSecurityPolicy: disabled by default with TLS enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/PodSecurityPolicy: disabled with TLS disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/PodSecurityPolicy: enabled with TLS enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-cleanup-serviceaccount.bats b/test/unit/tls-init-cleanup-serviceaccount.bats new file mode 100644 index 0000000000..3d5aef8619 --- /dev/null +++ b/test/unit/tls-init-cleanup-serviceaccount.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInitCleanup/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ServiceAccount: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ServiceAccount: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInitCleanup/ServiceAccount: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInitCleanup/ServiceAccount: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-clusterrole.bats b/test/unit/tls-init-clusterrole.bats new file mode 100644 index 0000000000..b842e97c0d --- /dev/null +++ b/test/unit/tls-init-clusterrole.bats @@ -0,0 +1,67 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInit/ClusterRole: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRole: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRole: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRole: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/ClusterRole: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/ClusterRole: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrole.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[] | select(.resources==["podsecuritypolicies"]) | .resourceNames[0]' | tee /dev/stderr) + + [ "${actual}" = "release-name-consul-tls-init" ] +} diff --git a/test/unit/tls-init-clusterrolebinding.bats b/test/unit/tls-init-clusterrolebinding.bats new file mode 100644 index 0000000000..b9e5478ebb --- /dev/null +++ b/test/unit/tls-init-clusterrolebinding.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInit/ClusterRoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRoleBinding: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRoleBinding: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/ClusterRoleBinding: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ClusterRoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-clusterrolebinding.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-job.bats b/test/unit/tls-init-job.bats new file mode 100644 index 0000000000..d86f7e511c --- /dev/null +++ b/test/unit/tls-init-job.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInit/Job: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/Job: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/Job: enabled with global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/Job: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/Job: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/Job: sets additional IP SANs when provided and global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.serverAdditionalIPSANs[0]=1.1.1.1' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-additional-ipaddress=1.1.1.1"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/Job: sets additional DNS SANs when provided and global.tls.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.serverAdditionalDNSSANs[0]=example.com' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-additional-dnsname=example.com"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-podsecuritypolicy.bats b/test/unit/tls-init-podsecuritypolicy.bats new file mode 100644 index 0000000000..3554e483d0 --- /dev/null +++ b/test/unit/tls-init-podsecuritypolicy.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInit/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/PodSecurityPolicy: disabled by default with TLS enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/PodSecurityPolicy: disabled with TLS disabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=false' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/PodSecurityPolicy: enabled with TLS enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-podsecuritypolicy.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/tls-init-serviceaccount.bats b/test/unit/tls-init-serviceaccount.bats new file mode 100644 index 0000000000..2ed13a49d3 --- /dev/null +++ b/test/unit/tls-init-serviceaccount.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load _helpers + +@test "tlsInit/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ServiceAccount: disabled with global.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ServiceAccount: enabled with global.tls.enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/ServiceAccount: disabled when server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "tlsInit/ServiceAccount: enabled when global.tls.enabled=true and server.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/ui-service.bats b/test/unit/ui-service.bats index f369e03168..c86b067cd3 100755 --- a/test/unit/ui-service.bats +++ b/test/unit/ui-service.bats @@ -136,3 +136,48 @@ load _helpers yq -r '.spec.loadBalancerIP' | tee /dev/stderr) [ "${actual}" = "1.2.3.4" ] } + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "ui/Service: no HTTPS listener when TLS is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.tls.enabled=false' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "https") | .port' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "ui/Service: HTTPS listener set when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "https") | .port' | tee /dev/stderr) + [ "${actual}" == "443" ] +} + +@test "ui/Service: HTTP listener still active when httpsOnly is disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=false' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "http") | .port' | tee /dev/stderr) + [ "${actual}" == "80" ] +} + +@test "ui/Service: no HTTP listener when httpsOnly is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ui-service.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.httpsOnly=true' \ + . | tee /dev/stderr | + yq -r '.spec.ports[] | select(.name == "http") | .port' | tee /dev/stderr) + [ "${actual}" == "" ] +} diff --git a/values.yaml b/values.yaml index e3f93caecc..1610131a8f 100644 --- a/values.yaml +++ b/values.yaml @@ -40,7 +40,7 @@ global: # remove these checks to make the sync work. # If using bootstrapACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. - imageK8S: "hashicorp/consul-k8s:0.10.1" + imageK8S: "hashicorp/consul-k8s:0.11.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running @@ -60,7 +60,7 @@ global: # # The secret can be created by running: # kubectl create secret generic consul-gossip-encryption-key \ - # --from-literal=key=$(consul keygen)`. + # --from-literal=key=$(consul keygen). # # In this case, secretName would be "consul-gossip-encryption-key" and # secretKey would be "key". @@ -77,6 +77,40 @@ global: # Additionally requires Consul >= 1.4 and consul-k8s >= 0.10.1. bootstrapACLs: false + # Enables TLS encryption across the cluster to verify authenticity of the + # servers and clients that connect. Note: It is HIGHLY recommended that you also + # enable Gossip encryption. + # See https://learn.hashicorp.com/consul/security-networking/agent-encryption + # + # Note: this relies on functionality introduced with Consul 1.4.1. Make sure + # your global.image value is at least version 1.4.1. + tls: + enabled: false + + # serverAdditionalDNSSANs is a list of additional DNS names to + # set as Subject Alternative Names (SANs) in the server certificate. + # This is useful when you need to access the Consul server(s) externally, + # for example, if you're using the UI. + serverAdditionalDNSSANs: [] + + # serverAdditionalIPSANs is a list of additional IP addresses to + # set as Subject Alternative Names (SANs) in the server certificate. + # This is useful when you need to access Consul server(s) externally, + # for example, if you're using the UI. + serverAdditionalIPSANs: [] + + # If verify is true, 'verify_outgoing', 'verify_server_hostname', and + # 'verify_incoming_rpc' will be set to true for Consul servers and clients. + # Set this to false to incrementally roll out TLS on an existing Consul cluster. + # Note: remember to switch it back to true once the rollout is complete. + # Please see this guide for more details: + # https://learn.hashicorp.com/consul/security-networking/certificates + verify: true + + # If httpsOnly is true, Consul will disable the HTTP port on both + # clients and servers and only accept HTTPS connections. + httpsOnly: true + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. @@ -240,7 +274,7 @@ client: # - operator: "Exists" tolerations: "" - # nodeSelector labels for client pod assignment, formatted as a muli-line string. + # nodeSelector labels for client pod assignment, formatted as a multi-line string. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector # Example: # nodeSelector: | @@ -426,7 +460,7 @@ syncCatalog: secretName: null secretKey: null - # nodeSelector labels for syncCatalog pod assignment, formatted as a muli-line string. + # nodeSelector labels for syncCatalog pod assignment, formatted as a multi-line string. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector # Example: # nodeSelector: | @@ -470,7 +504,7 @@ connectInject: # webhook. By default, the injector will generate and manage its own certs, # but this requires the ability for the injector to update its own # MutatingWebhookConfiguration. In a production environment, custom certs - # should probaly be used. Configure the values below to enable this. + # should probably be used. Configure the values below to enable this. certs: # secretName is the name of the secret that has the TLS certificate and # private key to serve the injector webhook. If this is null, then the From 7940818afc662fb3232e955f46e23b708f45a146 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 10 Jan 2020 15:31:47 -0800 Subject: [PATCH 286/739] Update CHANGELOG --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae080c1941..1bdd1abf50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ IMPROVEMENTS: on Kubernetes. We will have better support for other deployment architectures, as well as bringing your own CA, in the future. + * Use the latest version of consul-k8s (0.11.0). + + * Add pod name as metadata to client nodes to help users map nodes in Consul to underlying client pods + [[GH-315](https://github.com/hashicorp/consul-helm/pull/315)]. + + * Rename `enterprise-licence.yaml` template to `enterprise-license-job.yaml` [[GH-321](https://github.com/hashicorp/consul-helm/pull/321)]. + BUG FIXES: * Fix graceful termination for servers [[GH-313](https://github.com/hashicorp/consul-helm/pull/313)]. @@ -19,6 +26,11 @@ BUG FIXES: This replaces the `preStop` hook that was calling `consul leave`. Note that `leave_on_terminate` defaults to true for clients as of Consul `0.7`, so this change only affects earlier versions. + * Helm test runner now respects the provided namespace [[GH-320](https://github.com/hashicorp/consul-helm/pull/320)]. + + * Add pod security policies for the `enterprise-license` [[GH-325](https://github.com/hashicorp/consul-helm/pull/325)] + and the `server-acl-init` jobs [[GH-326](https://github.com/hashicorp/consul-helm/pull/325)]. + ## 0.15.0 (Dec 17, 2019) BREAKING CHANGES: From 6275fea8f2524d156e1b78479ca3e41d8b88b972 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 10 Jan 2020 15:33:48 -0800 Subject: [PATCH 287/739] Release 0.16.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bdd1abf50..0a28afb94d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.16.0 (Jan 10, 2020) + IMPROVEMENTS: * Optionally allow enabling TLS for Consul communication [[GH-313](https://github.com/hashicorp/consul-helm/pull/313)]. From 96595824279595b29f6dfc0ff57c00ee5c822da8 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 13 Jan 2020 14:25:05 -0800 Subject: [PATCH 288/739] Update CHANGELOG (#331) --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a28afb94d..60860bbcaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ IMPROVEMENTS: on Kubernetes. We will have better support for other deployment architectures, as well as bringing your own CA, in the future. + Also, note that simply turning on this feature and running `helm upgrade` will result in downtime if you are using + Consul Connect or Sync Catalog features. We will be adding instructions on how to do this upgrade without downtime soon. + Additionally, if you do decide to proceed with an upgrade despite downtime + and you're using Consul Connect, all application pods need to be recreated after upgrade, so that the Connect injector + can re-inject Envoy sidecars with TLS enabled. + * Use the latest version of consul-k8s (0.11.0). * Add pod name as metadata to client nodes to help users map nodes in Consul to underlying client pods From c2a47117a920410b7e461d420a98dfa39603c69d Mon Sep 17 00:00:00 2001 From: tehmoon Date: Tue, 14 Jan 2020 12:13:06 -0500 Subject: [PATCH 289/739] Update tls-init-job.yaml (#329) --- templates/tls-init-job.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index 30c8c02a98..be5f62b89c 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -45,7 +45,8 @@ spec: - "/bin/sh" - "-ec" - | - consul tls ca create + consul tls ca create \ + -domain={{ .Values.global.domain }} consul tls cert create -server \ -days=730 \ -additional-dnsname='{{ template "consul.fullname" . }}-server' \ From 85093b663326b54b06eb2b3e9571cac153949b63 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 14 Jan 2020 10:56:44 -0800 Subject: [PATCH 290/739] Update CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60860bbcaa..458f0eb5b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Unreleased +## 0.16.1 (Jan 14, 2020) + +BUG FIXES: + + * Fix a bug with the `tls-init` job, in which it could not correctly detect CA file + if Consul domain is provided [[GH-329](https://github.com/hashicorp/consul-helm/pull/329)]. + ## 0.16.0 (Jan 10, 2020) IMPROVEMENTS: From bdb5aae34eb17ae2aefb2a78ecd4d20d70782c77 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 14 Jan 2020 16:43:41 -0800 Subject: [PATCH 291/739] Update Chart Version --- Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index a48200cace..d764685444 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.15.0 +version: 0.16.1 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From c3373f85486dcbbba9e99025d20d2b612e7bc1d4 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Wed, 15 Jan 2020 10:39:33 -0800 Subject: [PATCH 292/739] Release 0.16.2 --- CHANGELOG.md | 6 ++++++ Chart.yaml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 458f0eb5b9..08fd15b0df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Unreleased +## 0.16.2 (Jan 15, 2020) + +BUG FIXES: + + * Fix Helm Chart version. + ## 0.16.1 (Jan 14, 2020) BUG FIXES: diff --git a/Chart.yaml b/Chart.yaml index d764685444..72e374886c 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.16.1 +version: 0.16.2 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From b496bcc76e8aa8e41e0ed2aa590396fc9764af5a Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 16 Jan 2020 10:29:54 -0600 Subject: [PATCH 293/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08fd15b0df..81d645c99a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -203,6 +203,10 @@ IMPROVEMENTS: ## 0.7.0 (March 21, 2019) +BREAKING CHANGES: + + * If previously setting the release name to `consul`, you must now set `fullnameOverride: consul` in your config to prevent all resources being renamed. + IMPROVEMENTS: * Support pod PriorityClasses for Consul servers and clients From 505e918c101bbf286e8ac8353e2783608e78bedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Siedlarek?= Date: Sun, 26 Jan 2020 22:49:31 +0100 Subject: [PATCH 294/739] Fixed template newline issue in connect-inject. Lack of template whitespace stripping in one particular line of connect-inject deployment was causing all the remaining command arguments to be ignored when using `connectInject.overrideAuthMethodName` option. --- templates/connect-inject-deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 59581e8c91..35757c78be 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -57,7 +57,7 @@ spec: -listen=:8080 \ {{- if .Values.connectInject.overrideAuthMethodName }} -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ - {{ else if .Values.global.bootstrapACLs }} + {{- else if .Values.global.bootstrapACLs }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} {{- if .Values.global.tls.enabled }} From 83acf1ebf3f48e1de10fefc1641a1aa169dbd77f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 7 Feb 2020 16:46:53 -0700 Subject: [PATCH 295/739] Continuously retry applying license Previously, if the leader wasn't elected, the consul license command would be run once in each execution of the job and fail. On clusters where the servers took a long time to come up, the job would reach its maximum backoff limit and the license would never be applied. This change runs the license put command in a loop until it's successful or it times out after 20 minutes. --- templates/enterprise-license-job.yaml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 910aecbadf..e53a7d1b64 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -65,9 +65,25 @@ spec: {{- end}} command: - "/bin/sh" - - "-ec" + - "-c" - | - consul license put "${ENTERPRISE_LICENSE}" + # Create a script that we can execute with the timeout command. + cat > apply-license.sh << 'EOF' + #!/bin/sh + while true; do + echo "Applying license..." + if consul license put "${ENTERPRISE_LICENSE}"; then + echo "License applied successfully" + break + fi + echo "Retrying in 2s..." + sleep 2 + done + EOF + chmod +x ./apply-license.sh + + # Time out after 20 minutes. + timeout -t 1200 ./apply-license.sh {{- if .Values.global.tls.enabled }} volumeMounts: - name: tls-ca-cert From e4e329b56a857c5f0766df42cf8ea1eeab1c0e11 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Wed, 18 Dec 2019 15:22:04 -0800 Subject: [PATCH 296/739] Add namespace support to the Helm chart Namespaces: Adds a global `enableNamespaces` variable, as well as namespace options to catalog sync and connect inject. Both of these can register into (1) a single Consul namespace, (2) mirror the k8s namespaces, or (3) mirror the k8s namespaces with a prefix. Adds an ACL token for the connect injector that is necessary for it to create namespaces. Beyond namespaces: Additionally, both catalog sync and connect inject now have richer namespace selectors with allow and deny lists. Updates default version of Envoy to 1.13.0, Consul to 1.7.1 and consul-k8s to 0.12. --- templates/connect-inject-clusterrole.yaml | 9 + templates/connect-inject-deployment.yaml | 64 ++++ templates/enterprise-license-job.yaml | 2 + templates/server-acl-init-job.yaml | 30 +- templates/sync-catalog-deployment.yaml | 21 ++ test/unit/connect-inject-clusterrole.bats | 64 ++++ test/unit/connect-inject-deployment.bats | 349 +++++++++++++++++++ test/unit/mesh-gateway-deployment.bats | 2 +- test/unit/server-acl-init-job.bats | 402 ++++++++++++++++++++++ test/unit/sync-catalog-deployment.bats | 190 ++++++++++ values.yaml | 130 ++++++- 11 files changed, 1257 insertions(+), 6 deletions(-) diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 08f84d294b..158eaea2fe 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -25,4 +25,13 @@ rules: verbs: - use {{- end }} +{{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} +- apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-connect-inject-acl-token + verbs: + - get +{{- end }} {{- end }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 35757c78be..c60319b10a 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -41,6 +41,35 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- /* A Consul client and ACL token is only necessary for the connect injector if namespaces are enabled */}} + {{- if .Values.global.enableConsulNamespaces }} + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if (and .Values.connectInject.aclInjectToken.secretName .Values.connectInject.aclInjectToken.secretKey) }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.connectInject.aclInjectToken.secretName }} + key: {{ .Values.connectInject.aclInjectToken.secretKey }} + {{- else if .Values.global.bootstrapACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ template "consul.fullname" . }}-connect-inject-acl-token" + key: "token" + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + {{- end }} command: - "/bin/sh" - "-ec" @@ -60,6 +89,7 @@ spec: {{- else if .Values.global.bootstrapACLs }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} + {{- if .Values.global.tls.enabled }} -consul-ca-cert=/consul/tls/ca/tls.crt \ {{- end }} @@ -69,6 +99,27 @@ spec: {{- if (and .Values.connectInject.centralConfig.enabled .Values.connectInject.centralConfig.defaultProtocol) }} -default-protocol="{{ .Values.connectInject.centralConfig.defaultProtocol }}" \ {{- end }} + {{- range $value := .Values.connectInject.k8sAllowNamespaces }} + -allow-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- range $value := .Values.connectInject.k8sDenyNamespaces }} + -deny-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + -consul-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + -enable-k8s-namespace-mirroring=true \ + {{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} + -k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- if .Values.global.bootstrapACLs }} + -consul-cross-namespace-acl-policy=cross-namespace-policy \ + {{- end }} + {{- end }} {{- if .Values.connectInject.certs.secretName }} -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \ -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} @@ -122,6 +173,19 @@ spec: secretName: {{ template "consul.fullname" . }}-ca-cert {{- end }} {{- end }} + {{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} + initContainers: + - name: injector-acl-init + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s acl-init \ + -secret-name="{{ template "consul.fullname" . }}-connect-inject-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" + {{- end }} {{- if .Values.connectInject.nodeSelector }} nodeSelector: {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 910aecbadf..0479704eea 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -28,6 +28,8 @@ spec: chart: {{ template "consul.chart" . }} release: {{ .Release.Name }} component: license + annotations: + "consul.hashicorp.com/connect-inject": "false" spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index adb7b918d5..90ff27f8d4 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -72,7 +72,7 @@ spec: -allow-dns=true \ {{- end }} {{- if .Values.connectInject.enabled }} - -create-inject-token=true \ + -create-inject-auth-method=true \ {{- end }} {{- if .Values.meshGateway.enabled }} -create-mesh-gateway-token=true \ @@ -89,6 +89,34 @@ spec: {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -create-client-token=false \ {{- end }} + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- /* syncCatalog must be enabled to set sync flags */}} + {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} + {{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} + -consul-sync-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }} + -enable-sync-k8s-namespace-mirroring=true \ + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} + -sync-k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- end }} + {{- /* connectInject must be enabled to set inject flags */}} + {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} + -create-inject-namespace-token=true \ + {{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + -consul-inject-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + -enable-inject-k8s-namespace-mirroring=true \ + {{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} + -inject-k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- end }} + {{- end }} -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 5ad4d6cbf9..39afef9d2a 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -95,6 +95,12 @@ spec: {{- if .Values.syncCatalog.k8sSourceNamespace }} -k8s-source-namespace="{{ .Values.syncCatalog.k8sSourceNamespace}}" \ {{- end }} + {{- range $value := .Values.syncCatalog.k8sAllowNamespaces }} + -allow-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- range $value := .Values.syncCatalog.k8sDenyNamespaces }} + -deny-k8s-namespace="{{ $value }}" \ + {{- end }} -k8s-write-namespace=${NAMESPACE} \ {{- if (not .Values.syncCatalog.syncClusterIPServices) }} -sync-clusterip-services=false \ @@ -117,6 +123,21 @@ spec: {{- if .Values.syncCatalog.addK8SNamespaceSuffix}} -add-k8s-namespace-suffix \ {{- end}} + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} + -consul-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }} + -enable-k8s-namespace-mirroring=true \ + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} + -k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- if .Values.global.bootstrapACLs }} + -consul-cross-namespace-acl-policy=cross-namespace-policy \ + {{- end }} + {{- end }} livenessProbe: httpGet: path: /health/ready diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats index 45b5c7cbc3..df66a8d32f 100644 --- a/test/unit/connect-inject-clusterrole.bats +++ b/test/unit/connect-inject-clusterrole.bats @@ -53,3 +53,67 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "connectInject/ClusterRole: no podsecuritypolicies access with global.enablePodSecurityPolicies=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=false' \ + . | tee /dev/stderr | + yq -r '.rules | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "connectInject/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules[1].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs for namespaces + +@test "connectInject/ClusterRole: does not allow secret access with global.bootsrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.rules | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "connectInject/ClusterRole: allow secret access with global.bootsrapACLs=true and global.enableConsulNamespaces=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq -r '.rules[1].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} + +@test "connectInject/ClusterRole: allows secret access with bootsrapACLs, enablePodSecurityPolicies and enableConsulNamespaces all true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-clusterrole.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq -r '.rules[2].resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index aa748f156e..b2aac0eac2 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -409,3 +409,352 @@ load _helpers yq '.spec.template.spec.containers[0].volumeMounts | length' | tee /dev/stderr) [ "${actual}" = "2" ] } + +#-------------------------------------------------------------------- +# k8sAllowNamespaces & k8sDenyNamespaces + +@test "connectInject/Deployment: default is allow '*', deny nothing" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'map(select(test("allow-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'any(contains("allow-k8s-namespace=\"*\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'map(select(test("deny-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "0" ] +} + +@test "connectInject/Deployment: can set allow and deny" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.k8sAllowNamespaces[0]=allowNamespace' \ + --set 'connectInject.k8sDenyNamespaces[0]=denyNamespace' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'map(select(test("allow-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'map(select(test("deny-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'any(contains("allow-k8s-namespace=\"allowNamespace\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("deny-k8s-namespace=\"denyNamespace\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + +@test "connectInject/Deployment: namespace options disabled by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: namespace options set with .global.enableConsulNamespaces=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: mirroring options set with .connectInject.consulNamespaces.mirroringK8S=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.consulNamespaces.mirroringK8S=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: prefix can be set with .connectInject.consulNamespaces.mirroringK8SPrefix" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.consulNamespaces.mirroringK8S=true' \ + --set 'connectInject.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix=k8s-"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + acl token + +@test "connectInject/Deployment: aclInjectToken disabled when namespaces not enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.aclInjectToken.secretKey=bar' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: aclInjectToken disabled when secretName is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.aclInjectToken.secretKey=bar' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: aclInjectToken disabled when secretKey is missing" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.aclInjectToken.secretName=foo' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: aclInjectToken enabled when secretName and secretKey is provided" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.aclInjectToken.secretName=foo' \ + --set 'connectInject.aclInjectToken.secretKey=bar' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name]' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'map(select(test("CONSUL_HTTP_TOKEN"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +#-------------------------------------------------------------------- +# namespaces + global.bootstrapACLs + +@test "connectInject/Deployment: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] ' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'map(select(test("CONSUL_HTTP_TOKEN"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "connectInject/Deployment: init container is created when global.bootstrapACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "injector-acl-init" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: cross namespace policy is not added when global.bootstrapACLs=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: cross namespace policy is added when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + http address + +@test "connectInject/Deployment: CONSUL_HTTP_ADDR env variable not set when namespaces are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: CONSUL_HTTP_ADDR env variable set when namespaces are enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: CONSUL_HTTP_ADDR and CONSUL_CACERT env variables set when namespaces are enabled" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] ' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("CONSUL_CACERT"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + host ip + +@test "connectInject/Deployment: HOST_IP env variable not set when namespaces are disabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("HOST_IP"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: HOST_IP env variable set when namespaces are enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '[.spec.template.spec.containers[0].env[].name] | any(contains("HOST_IP"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 5461a0d193..738c45a557 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -274,7 +274,7 @@ key2: value2' \ --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) - [ "${actual}" = "envoyproxy/envoy:v1.10.0" ] + [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] } @test "meshGateway/Deployment: envoy image can be set" { diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 94ad1bd4eb..995d07c3b6 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -233,3 +233,405 @@ load _helpers actual=$(echo $command | jq -r '. | any(contains("-consul-tls-server-name=server.dc1.consul"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# namespaces + +@test "serverACLInit/Job: namespace options disabled by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# namespaces + sync + +@test "serverACLInit/Job: sync namespace options not set with namespaces enabled, sync disabled" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: sync namespace options set with .global.enableConsulNamespaces=true and sync enabled" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: sync mirroring options set with .syncCatalog.consulNamespaces.mirroringK8S=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: sync prefix can be set with .syncCatalog.consulNamespaces.mirroringK8SPrefix" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix=k8s-"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# namespaces + inject + +@test "serverACLInit/Job: inject namespace options not set with namespaces enabled, inject disabled" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.consulNamespaces.mirroringK8S=true' \ + --set 'connectInject.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: inject namespace options set with .global.enableConsulNamespaces=true and inject enabled" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: inject mirroring options set with .connectInject.consulNamespaces.mirroringK8S=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.consulNamespaces.mirroringK8S=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: inject prefix can be set with .connectInject.consulNamespaces.mirroringK8SPrefix" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.consulNamespaces.mirroringK8S=true' \ + --set 'connectInject.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-sync-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-sync-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("sync-k8s-namespace-mirroring-prefix=k8s-"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("create-inject-namespace-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-inject-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-inject-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index cce24f84ac..58ee7620b6 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -415,3 +415,193 @@ load _helpers actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) [ "${actual}" = "/consul/tls/ca/tls.crt" ] } + +#-------------------------------------------------------------------- +# k8sAllowNamespaces & k8sDenyNamespaces + +@test "syncCatalog/Deployment: default is allow `*`, deny kube-system and kube-public" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'map(select(test("allow-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'any(contains("allow-k8s-namespace=\"*\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("deny-k8s-namespace=\"kube-system\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("deny-k8s-namespace=\"kube-public\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: can set allow and deny namespaces { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.k8sAllowNamespaces[0]=allowNamespace' \ + --set 'syncCatalog.k8sDenyNamespaces[0]=denyNamespace' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'map(select(test("allow-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'map(select(test("deny-k8s-namespace"))) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] + + local actual=$(echo $object | + yq 'any(contains("allow-k8s-namespace=\"allowNamespace\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("deny-k8s-namespace=\"denyNamespace\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + +@test "syncCatalog/Deployment: namespace options disabled by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: namespace options set with .global.enableConsulNamespaces=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: mirroring options set with .syncCatalog.consulNamespaces.mirroringK8S=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: prefix can be set with .syncCatalog.consulNamespaces.mirroringK8SPrefix" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ + --set 'syncCatalog.consulNamespaces.mirroringK8SPrefix=k8s-' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'any(contains("enable-namespaces=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("consul-destination-namespace=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("enable-k8s-namespace-mirroring=true"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'any(contains("k8s-namespace-mirroring-prefix=k8s-"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# namespaces + global.bootstrapACLs + +@test "syncCatalog/Deployment: cross namespace policy is not added when global.bootstrapACLs=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "syncCatalog/Deployment: cross namespace policy is added when global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 1610131a8f..e4a22e516a 100644 --- a/values.yaml +++ b/values.yaml @@ -30,7 +30,7 @@ global: # image: "consul:1.5.0" # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" - image: "consul:1.6.2" + image: "consul:1.7.1" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as catalog sync. This can be overridden @@ -40,7 +40,8 @@ global: # remove these checks to make the sync work. # If using bootstrapACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. - imageK8S: "hashicorp/consul-k8s:0.11.0" + # If using Consul Enterprise namespaces, must be >= 0.12. + imageK8S: "hashicorp/consul-k8s:0.12.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running @@ -111,6 +112,14 @@ global: # clients and servers and only accept HTTPS connections. httpsOnly: true + # [Enterprise Only] enableConsulNamespaces indicates that you are running + # Consul Enterprise v1.7+ with a valid Consul Enterprise license and would like to + # make use of configuration beyond registering everything into the `default` Consul + # namespace. Requires consul-k8s v0.12+. + # Additional configuration options are found in the `consulNamespaces` section + # of both the catalog sync and connect injector. + enableConsulNamespaces: false + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. @@ -412,11 +421,62 @@ syncCatalog: # prepended with "consul-". (Consul -> Kubernetes sync) k8sPrefix: null + # k8sAllowNamespaces is a list of k8s namespaces to sync the k8s services from. + # If a k8s namespace is not included in this list or is listed in `k8sDenyNamespaces`, + # services in that k8s namespace will not be synced even if they are explicitly + # annotated. Use ["*"] to automatically allow all k8s namespaces. + # + # For example, ["namespace1", "namespace2"] will only allow services in the k8s + # namespaces `namespace1` and `namespace2` to be synced and registered + # with Consul. All other k8s namespaces will be ignored. + # + # To deny all namespaces, set this to []. + # + # Note: `k8sDenyNamespaces` takes precedence over values defined here. + # Requires consul-k8s v0.12+ + k8sAllowNamespaces: ["*"] + + # k8sDenyNamespaces is a list of k8s namespaces that should not have their + # services synced. This list takes precedence over `k8sAllowNamespaces`. + # `*` is not supported because then nothing would be allowed to sync. + # Requires consul-k8s v0.12+. + # + # For example, if `k8sAllowNamespaces` is `["*"]` and `k8sDenyNamespaces` is + # `["namespace1", "namespace2"]`, then all k8s namespaces besides "namespace1" + # and "namespace2" will be synced. + k8sDenyNamespaces: ["kube-system", "kube-public"] + + # [DEPRECATED] Use k8sAllowNamespaces and k8sDenyNamespaces instead. For + # backwards compatibility, if both this and the allow/deny lists are set, + # the allow/deny lists will be ignored. # k8sSourceNamespace is the Kubernetes namespace to watch for service # changes and sync to Consul. If this is not set then it will default # to all namespaces. k8sSourceNamespace: null + # [Enterprise Only] These settings manage the catalog sync's interaction with + # Consul namespaces (requires consul-ent v1.7+ and consul-k8s v0.12+). + # Also, `global.enableConsulNamespaces` must be true. + consulNamespaces: + # consulDestinationNamespace is the name of the Consul namespace to register all + # k8s services into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # mirroringK8S causes k8s services to be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. + # `addK8SNamespaceSuffix` may no longer be needed if enabling this option. + mirroringK8S: false + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # service in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + # addK8SNamespaceSuffix appends Kubernetes namespace suffix to # each service name synced to Consul, separated by a dash. # For example, for a service 'foo' in the default namespace, @@ -499,6 +559,58 @@ connectInject: # namespace-label: label-value namespaceSelector: null + # k8sAllowNamespaces is a list of k8s namespaces to allow Connect sidecar + # injection in. If a k8s namespace is not included or is listed in `k8sDenyNamespaces`, + # pods in that k8s namespace will not be injected even if they are explicitly + # annotated. Use ["*"] to automatically allow all k8s namespaces. + # + # For example, ["namespace1", "namespace2"] will only allow pods in the k8s + # namespaces `namespace1` and `namespace2` to have Connect sidecars injected + # and registered with Consul. All other k8s namespaces will be ignored. + # + # To deny all namespaces, set this to []. + # + # Note: `k8sDenyNamespaces` takes precedence over values defined here and + # `namespaceSelector` takes precedence over both since it is applied first. + # `kube-system` and `kube-public` are never injected, even if included here. + # Requires consul-k8s v0.12+ + k8sAllowNamespaces: ["*"] + + # k8sDenyNamespaces is a list of k8s namespaces that should not allow Connect + # sidecar injection. This list takes precedence over `k8sAllowNamespaces`. + # `*` is not supported because then nothing would be allowed to be injected. + # + # For example, if `k8sAllowNamespaces` is `["*"]` and k8sDenyNamespaces is + # `["namespace1", "namespace2"]`, then all k8s namespaces besides "namespace1" + # and "namespace2" will be available for injection. + # + # Note: `namespaceSelector` takes precedence over this since it is applied first. + # `kube-system` and `kube-public` are never injected. + # Requires consul-k8s v0.12+. + k8sDenyNamespaces: [] + + # [Enterprise Only] These settings manage the connect injector's interaction with + # Consul namespaces (requires consul-ent v1.7+ and consul-k8s v0.12+). + # Also, `global.enableConsulNamespaces` must be true. + consulNamespaces: + # consulDestinationNamespace is the name of the Consul namespace to register all + # k8s pods into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # mirroringK8S causes k8s pods to be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. + mirroringK8S: false + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # pod in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + # The certs section configures how the webhook TLS certs are configured. # These are the TLS certs for the Kube apiserver communicating to the # webhook. By default, the injector will generate and manage its own certs, @@ -547,6 +659,16 @@ connectInject: # method for Connect inject, set this to the name of your auth method. overrideAuthMethodName: "" + # aclInjectToken refers to a Kubernetes secret that you have created that contains + # an ACL token for your Consul cluster which allows the Connect injector the correct + # permissions. This is only needed if Consul namespaces [Enterprise only] and ACLs + # are enabled on the Consul cluster and you are not setting `global.bootstrapACLs` + # to `true`. This token needs to have `operator = "write"` privileges to be able to + # create Consul namespaces. + aclInjectToken: + secretName: null + secretKey: null + # Requires Consul >= v1.5 and consul-k8s >= v0.8.1. centralConfig: # enabled controls whether central config is enabled on all servers and clients. @@ -639,8 +761,8 @@ meshGateway: # Optional YAML string that will be appended to the Service spec. additionalSpec: null - # Envoy image to use. - imageEnvoy: envoyproxy/envoy:v1.10.0 + # Envoy image to use. For Consul v1.7+, Envoy version 1.13+ is required. + imageEnvoy: envoyproxy/envoy:v1.13.0 # If set to true, gateway Pods will run on the host network. hostNetwork: false From cb8dc5e540b4d21e72f5ff2781dbc1ed89e1f3fe Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig Date: Thu, 20 Feb 2020 17:50:05 -0800 Subject: [PATCH 297/739] Update changelog for namespaces --- CHANGELOG.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Chart.yaml | 2 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81d645c99a..201a4ffc6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,99 @@ ## Unreleased +BREAKING CHANGES: + +* `consul-k8s` `v0.12.0`+ is now required. The chart is passing new flags that are only available in this version. + To use this version if not using the chart defaults, set + ```yaml + global: + imageK8S: hashicorp/consul-k8s:0.12.0 + ``` + +IMPROVEMENTS: + +* Catalog Sync + * New Helm values have been added to configure which Kubernetes namespaces we will sync from. The defaults are shown below: + ```yaml + syncCatalog: + toConsul: true + k8sAllowNamespaces: ["*"] + k8sDenyNamespaces: ["kube-system", "kube-public"] + ``` + * If running Consul Enterprise 1.7.0+, Consul namespaces are supported. New Helm values have been added to allow configuring which + Consul namespaces Kubernetes services are synced to. See [https://www.consul.io/docs/platform/k8s/service-sync.html#consul-enterprise-namespaces](https://www.consul.io/docs/platform/k8s/service-sync.html#consul-enterprise-namespaces) for more details. + + ```yaml + global: + enableConsulNamespaces: true + syncCatalog: + consulNamespaces: + # consulDestinationNamespace is the name of the Consul namespace to register all + # k8s services into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # mirroringK8S causes k8s services to be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. + # `addK8SNamespaceSuffix` may no longer be needed if enabling this option. + mirroringK8S: false + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # service in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + ``` + +* Connect Inject + * New Helm values have been added to configure which Kubernetes namespaces we will inject pods in. The defaults are shown below: + ```yaml + connectInject: + k8sAllowNamespaces: ["*"] + k8sDenyNamespaces: [] + ``` + * If running Consul Enterprise 1.7.0+, Consul namespaces are supported. New Helm values have been added to allow configuring which Consul namespaces Kubernetes pods + are registered into. See [https://www.consul.io/docs/platform/k8s/connect.html#consul-enterprise-namespaces](https://www.consul.io/docs/platform/k8s/connect.html#consul-enterprise-namespaces) for more details. + ```yaml + global: + enableConsulNamespaces: true + + connectInject: + consulNamespaces: + # consulDestinationNamespace is the name of the Consul namespace to register all + # k8s pods into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # mirroringK8S causes k8s pods to be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. + mirroringK8S: false + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # pod in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + ``` + +BUG FIXES: + +* Fix template rendering bug when setting `connectInject.overrideAuthMethodName` [[GH-342](https://github.com/hashicorp/consul-helm/pull/342)] +* Set `"consul.hashicorp.com/connect-inject": "false"` annotation on enterprise license job so it is not connect injected [[GH-343](https://github.com/hashicorp/consul-helm/pull/343)] + +DEPRECATIONS: + +* `.syncCatalog.k8sSourceNamespace` should no longer be used. Instead, use the new `.syncCatalog.k8sAllowNamespaces` and `.syncCatalog.k8sDenyNamespaces` features. For backward compatibility, if both this and the allow/deny lists are set, the allow/deny lists will be ignored. + +NOTES: + +* Bootstrap ACLs: Previously, ACL policies were not updated after creation. Now, if namespaces are enabled, they are updated every time the ACL bootstrapper is run so that any namespace config changes can be adjusted. This change is only an issue if you are updating ACL policies after creation. + ## 0.16.2 (Jan 15, 2020) BUG FIXES: diff --git a/Chart.yaml b/Chart.yaml index 72e374886c..dc44a42125 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.16.2 +version: 0.17.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 20cfe5344bc77f1d1e7b9ed36cd850ee0b52ebcc Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 2 Mar 2020 17:08:54 -0500 Subject: [PATCH 298/739] Document envoy version requirements --- values.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/values.yaml b/values.yaml index e4a22e516a..0363d62c94 100644 --- a/values.yaml +++ b/values.yaml @@ -542,11 +542,14 @@ connectInject: image: null # image for consul-k8s that contains the injector default: false # true will inject by default, otherwise requires annotation - # imageConsul and imageEnvoy can be set to Docker images for Consul and - # Envoy, respectively. If the Consul image is not specified, the global - # default will be used. If the Envoy image is not specified, an early - # version of Envoy will be used. + # The Docker image for Consul to use when performing Connect injection. + # Defaults to global.image. imageConsul: null + + # The Docker image for envoy to use as the proxy sidecar when performing + # Connect injection. If using Consul 1.7+, the envoy version must be 1.13+. + # If not set, the image used depends on the consul-k8s version. For + # consul-k8s 0.12.0 the default is envoyproxy/envoy-alpine:v1.13.0. imageEnvoy: null # namespaceSelector is the selector for restricting the webhook to only From a70e71ea57f65d32ab725db573a7c159b37fb7cd Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 2 Mar 2020 18:45:46 -0800 Subject: [PATCH 299/739] Allow setting your own CA as a kube secret (#346) --- templates/client-daemonset.yaml | 24 +++++++-- .../client-snapshot-agent-deployment.yaml | 7 +++ templates/connect-inject-deployment.yaml | 7 +++ templates/enterprise-license-job.yaml | 11 +++- templates/mesh-gateway-deployment.yaml | 7 +++ templates/server-acl-init-job.yaml | 11 +++- templates/server-statefulset.yaml | 11 +++- templates/sync-catalog-deployment.yaml | 11 +++- templates/tests/test-runner.yaml | 7 +++ templates/tls-init-cleanup-clusterrole.yaml | 2 + templates/tls-init-cleanup-job.yaml | 2 + templates/tls-init-job.yaml | 54 ++++++++++++++----- test/unit/client-daemonset.bats | 32 ++++++++++- .../client-snapshot-agent-deployment.bats | 23 ++++++++ test/unit/connect-inject-deployment.bats | 23 ++++++++ test/unit/enterprise-license-job.bats | 25 +++++++++ test/unit/mesh-gateway-deployment.bats | 25 +++++++++ test/unit/server-acl-init-job.bats | 23 ++++++++ test/unit/server-statefulset.bats | 28 ++++++++-- test/unit/sync-catalog-deployment.bats | 23 ++++++++ test/unit/tls-init-job.bats | 35 ++++++++++++ values.yaml | 37 +++++++++++-- 22 files changed, 394 insertions(+), 34 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 94e96fdf86..f00d08cb78 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -68,12 +68,26 @@ spec: configMap: name: {{ template "consul.fullname" . }}-client-config {{- if .Values.global.tls.enabled }} - - name: tls-ca-cert + - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert - - name: tls-ca-key + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-ca-key secret: + {{- if .Values.global.tls.caKey.secretName }} + secretName: {{ .Values.global.tls.caKey.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-key + {{- end }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key - name: tls-client-cert emptyDir: # We're using tmpfs here so that @@ -191,7 +205,7 @@ spec: - name: config mountPath: /consul/config {{- if .Values.global.tls.enabled }} - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true - name: tls-client-cert @@ -304,10 +318,10 @@ spec: volumeMounts: - name: tls-client-cert mountPath: /consul/tls/client - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca/cert readOnly: true - - name: tls-ca-key + - name: consul-ca-key mountPath: /consul/tls/ca/key readOnly: true {{- end }} diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index e1d99e14e9..ec1cf52113 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -54,7 +54,14 @@ spec: {{- if .Values.global.tls.enabled }} - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} {{- end }} containers: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index c60319b10a..29d9580157 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -170,7 +170,14 @@ spec: {{- if .Values.global.tls.enabled }} - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} {{- end }} {{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index e87bda9c00..ddc6eff67d 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -35,9 +35,16 @@ spec: serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license {{- if .Values.global.tls.enabled }} volumes: - - name: tls-ca-cert + - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} containers: - name: apply-enterprise-license @@ -88,7 +95,7 @@ spec: timeout -t 1200 ./apply-license.sh {{- if .Values.global.tls.enabled }} volumeMounts: - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index b6c7cfa0a1..ff63e884d0 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -51,7 +51,14 @@ spec: {{- if .Values.global.tls.enabled }} - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} {{- if .Values.meshGateway.hostNetwork }} hostNetwork: {{ .Values.meshGateway.hostNetwork }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 90ff27f8d4..546c7d2233 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -34,9 +34,16 @@ spec: serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init {{- if .Values.global.tls.enabled }} volumes: - - name: tls-ca-cert + - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} containers: - name: post-install-job @@ -48,7 +55,7 @@ spec: fieldPath: metadata.namespace {{- if .Values.global.tls.enabled }} volumeMounts: - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 7f448f1822..f51b49bfec 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -59,9 +59,16 @@ spec: configMap: name: {{ template "consul.fullname" . }}-server-config {{- if .Values.global.tls.enabled }} - - name: tls-ca-cert + - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt - name: tls-server-cert secret: secretName: {{ template "consul.fullname" . }}-server-cert @@ -157,7 +164,7 @@ spec: - name: config mountPath: /consul/config {{- if .Values.global.tls.enabled }} - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca/ readOnly: true - name: tls-server-cert diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 39afef9d2a..23cb7f1a14 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -31,9 +31,16 @@ spec: serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog {{- if .Values.global.tls.enabled }} volumes: - - name: tls-ca-cert + - name: consul-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} containers: - name: consul-sync-catalog @@ -72,7 +79,7 @@ spec: {{- end }} {{- if .Values.global.tls.enabled }} volumeMounts: - - name: tls-ca-cert + - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 416d0cfd72..8f3388e739 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -16,7 +16,14 @@ spec: volumes: - name: tls-ca-cert secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt {{- end }} containers: - name: consul-test diff --git a/templates/tls-init-cleanup-clusterrole.yaml b/templates/tls-init-cleanup-clusterrole.yaml index 6f6a31542a..02cde16fd1 100644 --- a/templates/tls-init-cleanup-clusterrole.yaml +++ b/templates/tls-init-cleanup-clusterrole.yaml @@ -15,8 +15,10 @@ rules: resources: - secrets resourceNames: + {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }} - {{ template "consul.fullname" . }}-ca-cert - {{ template "consul.fullname" . }}-ca-key + {{- end }} - {{ template "consul.fullname" . }}-server-cert verbs: - delete diff --git a/templates/tls-init-cleanup-job.yaml b/templates/tls-init-cleanup-job.yaml index 7c9156714f..39cc531ef9 100644 --- a/templates/tls-init-cleanup-job.yaml +++ b/templates/tls-init-cleanup-job.yaml @@ -39,12 +39,14 @@ spec: - "/bin/sh" - "-ec" - | + {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }} curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-cert \ -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-key \ -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + {{- end }} curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-server-cert \ -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index be5f62b89c..3700a42853 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -29,6 +29,21 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-tls-init + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + volumes: + - name: consul-ca-cert + secret: + secretName: {{ .Values.global.tls.caCert.secretName }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-ca-key + secret: + secretName: {{ .Values.global.tls.caKey.secretName }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key + {{- end }} containers: - name: tls-init image: "{{ .Values.global.image }}" @@ -45,10 +60,28 @@ spec: - "/bin/sh" - "-ec" - | + {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }} consul tls ca create \ -domain={{ .Values.global.domain }} + curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.domain }}-agent-ca.pem | base64 | tr -d '\n' )\" }}" > /dev/null + curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-key\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.key\": \"$( cat {{ .Values.global.domain }}-agent-ca-key.pem | base64 | tr -d '\n' )\" }}" > /dev/null + {{- end }} consul tls cert create -server \ -days=730 \ + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + -ca=/consul/tls/ca/cert/tls.crt \ + -key=/consul/tls/ca/key/tls.key \ + {{- end }} -additional-dnsname='{{ template "consul.fullname" . }}-server' \ -additional-dnsname='*.{{ template "consul.fullname" . }}-server' \ -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}' \ @@ -61,23 +94,20 @@ spec: {{- end }} -dc={{ .Values.global.datacenter }} \ -domain={{ .Values.global.domain }} - curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ - https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ - -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ - -H "Content-Type: application/json" \ - -H "Accept: application/json" \ - -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.domain }}-agent-ca.pem | base64 | tr -d '\n' )\" }}" > /dev/null - curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ - https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ - -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ - -H "Content-Type: application/json" \ - -H "Accept: application/json" \ - -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-ca-key\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"Opaque\", \"data\": { \"tls.key\": \"$( cat {{ .Values.global.domain }}-agent-ca-key.pem | base64 | tr -d '\n' )\" }}" > /dev/null curl -s -X POST --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets \ -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d "{ \"kind\": \"Secret\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"{{ template "consul.fullname" . }}-server-cert\", \"namespace\": \"${NAMESPACE}\" }, \"type\": \"kubernetes.io/tls\", \"data\": { \"tls.crt\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0.pem | base64 | tr -d '\n' )\", \"tls.key\": \"$( cat {{ .Values.global.datacenter }}-server-{{ .Values.global.domain }}-0-key.pem | base64 | tr -d '\n' )\" } }" > /dev/null + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca/cert + readOnly: true + - name: consul-ca-key + mountPath: /consul/tls/ca/key + readOnly: true + {{- end }} {{- end }} {{- end }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 438d9a8763..6f13936002 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -430,7 +430,7 @@ load _helpers -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -613,6 +613,36 @@ load _helpers [ "${actual}" = "false" ] } +@test "client/DaemonSet: can overwrite CA secret with the provided one" { + cd `chart_dir` + local spec=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-cert") | .secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the provided ca key secret is attached as volume + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-key") | .secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-key" ] + + # check that the volumes pulls the provided secret keys as a CA cert + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-cert") | .secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] + + # check that the volumes pulls the provided secret keys as a CA key + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-key") | .secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + #-------------------------------------------------------------------- # extraEnvironmentVariables diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index ca8887f3f2..781664c89a 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -246,3 +246,26 @@ load _helpers yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "client/SnapshotAgentDeployment: can overwrite CA with the provided secret" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that it uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index b2aac0eac2..0a34871ff9 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -410,6 +410,29 @@ load _helpers [ "${actual}" = "2" ] } +@test "connectInject/Deployment: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + #-------------------------------------------------------------------- # k8sAllowNamespaces & k8sDenyNamespaces diff --git a/test/unit/enterprise-license-job.bats b/test/unit/enterprise-license-job.bats index 283dd163f0..3a8ce55af2 100644 --- a/test/unit/enterprise-license-job.bats +++ b/test/unit/enterprise-license-job.bats @@ -174,3 +174,28 @@ load _helpers yq -r '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) [ "${actual}" = "/consul/tls/ca/tls.crt" ] } + +@test "server/EnterpriseLicense: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + -x templates/enterprise-license-job.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 738c45a557..8523760de2 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -629,3 +629,28 @@ key2: value2' \ actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) [ "${actual}" = "/consul/tls/ca/tls.crt" ] } + +@test "meshGateway/Deployment: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 995d07c3b6..29150d45c0 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -234,6 +234,29 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/Job: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + #-------------------------------------------------------------------- # namespaces diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 4f5ade5783..a4930e5039 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -469,7 +469,7 @@ load _helpers -x templates/server-statefulset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -489,7 +489,7 @@ load _helpers -x templates/server-statefulset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-ca-cert")' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -624,7 +624,7 @@ load _helpers @test "server/StatefulSet: doesn't set the verify_* flags by default when global.tls.enabled and global.tls.verify is false" { cd `chart_dir` local command=$(helm template \ - -x templates/server-statefulset.yaml \ + -x templates/server-statefulset.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.verify=false' \ . | tee /dev/stderr | @@ -640,3 +640,25 @@ load _helpers actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) [ "${actual}" = "false" ] } + +@test "server/StatefulSet: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} \ No newline at end of file diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 58ee7620b6..e486ceae3e 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -416,6 +416,29 @@ load _helpers [ "${actual}" = "/consul/tls/ca/tls.crt" ] } +@test "syncCatalog/Deployment: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $ca_cert_volume | jq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + #-------------------------------------------------------------------- # k8sAllowNamespaces & k8sDenyNamespaces diff --git a/test/unit/tls-init-job.bats b/test/unit/tls-init-job.bats index d86f7e511c..23fae59bbd 100644 --- a/test/unit/tls-init-job.bats +++ b/test/unit/tls-init-job.bats @@ -75,3 +75,38 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-additional-dnsname=example.com"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "tlsInit/Job: can overwrite CA secret with the provided one" { + cd `chart_dir` + local spec=$(helm template \ + -x templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq '.spec.template.spec' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-cert") | .secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # uses the provided secret key for CA cert + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-cert") | .secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] + + # check that the provided ca key secret is attached as a volume + local actual + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-key") | .secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-key" ] + + # uses the provided secret key for CA cert + actual=$(echo $spec | jq -r '.volumes[] | select(.name=="consul-ca-key") | .secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] + + # check that it doesn't generate the CA + actual=$(echo $spec | jq -r '.containers[0].command | join(" ") | contains("consul tls ca create")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index e4a22e516a..24db77e9f3 100644 --- a/values.yaml +++ b/values.yaml @@ -112,6 +112,33 @@ global: # clients and servers and only accept HTTPS connections. httpsOnly: true + # caCert is a Kubernetes secret containing the certificate + # of the CA to use for TLS communication within the Consul cluster. + # If you have generated the CA yourself with the consul CLI, + # you could use the following command to create the secret in Kubernetes: + # + # kubectl create secret generic consul-ca-cert \ + # --from-file='tls.crt=./consul-agent-ca.pem' + caCert: + secretName: null + secretKey: null + + # caKey is a Kubernetes secret containing the private key + # of the CA to use for TLS communications within the Consul cluster. + # If you have generated the CA yourself with the consul CLI, + # you could use the following command to create the secret in Kubernetes: + # + # kubectl create secret generic consul-ca-key \ + # --from-file='tls.key=./consul-agent-ca-key.pem' + # + # Note that we need the CA key so that we can generate server and client certificates. + # It is particularly important for the client certificates since they need to have host IPs + # as Subject Alternative Names. In the future, we may support bringing your own server + # certificates. + caKey: + secretName: null + secretKey: null + # [Enterprise Only] enableConsulNamespaces indicates that you are running # Consul Enterprise v1.7+ with a valid Consul Enterprise license and would like to # make use of configuration beyond registering everything into the `default` Consul @@ -202,7 +229,7 @@ server: # in a PodSpec. tolerations: "" - # nodeSelector labels for server pod assignment, formatted as a muli-line string. + # nodeSelector labels for server pod assignment, formatted as a multi-line string. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector # Example: # nodeSelector: | @@ -218,7 +245,7 @@ server: # the annotations to apply to the server pods annotations: null - # extraEnvVars is a list of extra enviroment variables to set with the stateful set. These could be + # extraEnvVars is a list of extra environment variables to set with the stateful set. These could be # used to include proxy settings required for cloud auto-join feature, # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure # custom consul parameters. @@ -311,7 +338,7 @@ client: # the annotations to apply to the client pods annotations: null - # extraEnvVars is a list of extra enviroment variables to set with the pod. These could be + # extraEnvVars is a list of extra environment variables to set with the pod. These could be # used to include proxy settings required for cloud auto-join feature, # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure # custom consul parameters. @@ -333,7 +360,7 @@ client: # type: RollingUpdate updateStrategy: null - # snaphotAgent contains settings for setting up and running snapshot agents + # snapshotAgent contains settings for setting up and running snapshot agents # within the Consul clusters. They are required to be co-located with Consul # clients, so will inherit the clients' nodeSelector, tolerations and affinity. # This is an Enterprise feature only. @@ -635,7 +662,7 @@ connectInject: certName: tls.crt keyName: tls.key - # nodeSelector labels for connectInject pod assignment, formatted as a muli-line string. + # nodeSelector labels for connectInject pod assignment, formatted as a multi-line string. # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector # Example: # nodeSelector: | From 2f8648ee8f42882be130f180a0fb029bac5df43a Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 10 Feb 2020 09:56:54 -0700 Subject: [PATCH 300/739] Switch to contains() for command test --- test/unit/mesh-gateway-deployment.bats | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 8523760de2..c2edea3753 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -335,7 +335,7 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [[ $(echo "$actual" | yq -r '.command[2]') =~ '-address="${POD_IP}:443"' ]] + [ $(echo "$actual" | yq -r '.command | join(" ") | contains("-address=\"${POD_IP}:443\"")') = "true" ] [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "443" ] [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "443" ] [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "443" ] @@ -352,7 +352,7 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [[ $(echo "$actual" | yq -r '.command[2]') =~ '-address="${POD_IP}:8443"' ]] + [ $(echo "$actual" | yq -r '.command | join(" ") | contains("-address=\"${POD_IP}:8443\"")') = "true" ] [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "8443" ] [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "8443" ] [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] @@ -370,8 +370,8 @@ key2: value2' \ --set 'client.grpc=true' \ --set 'meshGateway.wanAddress.useNodeIP=true' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) - [[ "${actual}" =~ '-wan-address="${HOST_IP}:443"' ]] + yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:443\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "meshGateway/Deployment: wanAddress uses NodeIP by default" { @@ -382,8 +382,8 @@ key2: value2' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) - [[ "${actual}" =~ '-wan-address="${HOST_IP}:443"' ]] + yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:443\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "meshGateway/Deployment: wanAddress.useNodeIP" { @@ -396,8 +396,8 @@ key2: value2' \ --set 'meshGateway.wanAddress.useNodeIP=true' \ --set 'meshGateway.wanAddress.port=4444' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) - [[ "${actual}" =~ '-wan-address="${HOST_IP}:4444"' ]] + yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:4444\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "meshGateway/Deployment: wanAddress.useNodeName" { @@ -411,8 +411,8 @@ key2: value2' \ --set 'meshGateway.wanAddress.useNodeName=true' \ --set 'meshGateway.wanAddress.port=4444' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) - [[ "${actual}" =~ '-wan-address="${NODE_NAME}:4444"' ]] + yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${NODE_NAME}:4444\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "meshGateway/Deployment: wanAddress.host" { @@ -427,8 +427,8 @@ key2: value2' \ --set 'meshGateway.wanAddress.host=myhost' \ --set 'meshGateway.wanAddress.port=4444' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) - [[ "${actual}" =~ '-wan-address="myhost:4444"' ]] + yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"myhost:4444\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] } #-------------------------------------------------------------------- @@ -460,7 +460,7 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) - [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ '-service="mesh-gateway"' ]] + [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ "-service=\"mesh-gateway\"" ]] [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"mesh-gateway\"' ]] } @@ -475,7 +475,7 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) - [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ '-service="overridden"' ]] + [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ "-service=\"overridden\"" ]] [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"overridden\"' ]] } From 90cbb966463edecf070ea3fbefd6864a3c4c88e1 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 18 Feb 2020 10:26:20 -0700 Subject: [PATCH 301/739] Add new federation config This value enables mesh gateway federation. --- templates/mesh-gateway-deployment.yaml | 3 +++ templates/server-statefulset.yaml | 3 +++ templates/tls-init-job.yaml | 1 + test/unit/mesh-gateway-deployment.bats | 27 ++++++++++++++++++++++++++ test/unit/server-statefulset.bats | 25 +++++++++++++++++++++++- values.yaml | 9 +++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index ff63e884d0..ea7d8d70ed 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -165,6 +165,9 @@ spec: {{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }} -service={{ .Values.meshGateway.consulServiceName | quote }} \ {{- end }} + {{- if .Values.global.federation.enabled }} + -expose-servers \ + {{- end }} {{- if .Values.meshGateway.enableHealthChecks }} livenessProbe: tcpSocket: diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index f51b49bfec..e20f52a707 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -151,6 +151,9 @@ spec: {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ {{- end }} + {{- if .Values.global.federation.enabled }} + -hcl="connect { enable_mesh_gateway_wan_federation = true }" \ + {{- end }} {{- if .Values.ui.enabled }} -ui \ {{- end }} diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index 3700a42853..618035f60c 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -86,6 +86,7 @@ spec: -additional-dnsname='*.{{ template "consul.fullname" . }}-server' \ -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}' \ -additional-dnsname='*.{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc' \ + -additional-dnsname='*.server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }}' \ {{- range .Values.global.tls.serverAdditionalIPSANs }} -additional-ipaddress={{ . }} \ {{- end }} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index c2edea3753..f92ec1a602 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -654,3 +654,30 @@ key2: value2' \ actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) [ "${actual}" = "key" ] } + +#-------------------------------------------------------------------- +# global.federation.enabled + +@test "meshGateway/Deployment: -expose-servers set when federation.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.federation.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("-expose-servers")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: -expose-servers not set when federation.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.federation.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("-expose-servers")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index a4930e5039..b1e85626c6 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -661,4 +661,27 @@ load _helpers # check that the volume uses the provided secret key actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) [ "${actual}" = "key" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# global.federation.enabled + +@test "server/StatefulSet: mesh gateway federation enabled when federation.enabled=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.federation.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("connect { enable_mesh_gateway_wan_federation = true }")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: mesh gateway federation not enabled when federation.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.federation.enabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("connect { enable_mesh_gateway_wan_federation = true }")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 24db77e9f3..80c7b4184e 100644 --- a/values.yaml +++ b/values.yaml @@ -147,6 +147,15 @@ global: # of both the catalog sync and connect injector. enableConsulNamespaces: false + # Configures Consul datacenter federation. + federation: + # If true, servers and mesh gateways will + # have mesh gateway federation enabled. + # Additional configuration will be needed to provide the addresses of the + # remote datacenter's mesh gateway to federate with. + # This setting must be true in both primary and secondary datacenters. + enabled: false + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From f9a536d2e87395491bde812f5105cc5fcdabc399 Mon Sep 17 00:00:00 2001 From: jb-abbadie Date: Fri, 6 Mar 2020 10:54:54 +0100 Subject: [PATCH 302/739] Add custom annotation for service --- templates/server-service.yaml | 3 +++ test/unit/server-service.bats | 22 ++++++++++++++++++++++ values.yaml | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 4abaf8a25d..0a619cf385 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -15,6 +15,9 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} annotations: + {{- if .Values.server.service.annotations }} + {{ tpl .Values.server.service.annotations . | nindent 4 | trim }} + {{- end }} # This must be set in addition to publishNotReadyAddresses due # to an open issue where it may not work: # https://github.com/kubernetes/kubernetes/issues/58662 diff --git a/test/unit/server-service.bats b/test/unit/server-service.bats index d1c180ec4b..2c91b877f2 100755 --- a/test/unit/server-service.bats +++ b/test/unit/server-service.bats @@ -103,3 +103,25 @@ load _helpers yq -r '.spec.ports[] | select(.name == "http") | .port' | tee /dev/stderr) [ "${actual}" == "" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "server/Service: one annotation by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + . | tee /dev/stderr | + yq -r '.metadata.annotations | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "server/Service: can set annotations" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-service.yaml \ + --set 'server.service.annotations=key: value' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} diff --git a/values.yaml b/values.yaml index 700121471e..e62fd2b538 100644 --- a/values.yaml +++ b/values.yaml @@ -245,6 +245,11 @@ server: # the annotations to apply to the server pods annotations: null + service: + # This should be a multi-line string mapping directly to the a map of + # the annotations to apply to the server service + annotations: null + # extraEnvVars is a list of extra environment variables to set with the stateful set. These could be # used to include proxy settings required for cloud auto-join feature, # in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure From 8aac3f6552a74e5631fd9b417c234260a23f0390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Apayd=C4=B1n?= Date: Mon, 9 Mar 2020 18:18:09 +0200 Subject: [PATCH 303/739] helm3 support for NOTES.txt (#369) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * helm3 support for NOTES.txt Signed-off-by: Batuhan Apaydın --- templates/NOTES.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/templates/NOTES.txt b/templates/NOTES.txt index 26d90c9ed5..d7b2bde29e 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -7,11 +7,18 @@ Consul with Kubernetes available here: https://www.consul.io/docs/platform/k8s/index.html -Your release is named {{ .Release.Name }}. To learn more about the release, try: +Your release is named {{ .Release.Name }}. + +To learn more about the release if you are using Helm 2, run: $ helm status {{ .Release.Name }} $ helm get {{ .Release.Name }} +To learn more about the release if you are using Helm 3, run: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + {{- if (and .Values.global.bootstrapACLs (gt (len .Values.server.extraConfig) 3)) }} Warning: Defining server extraConfig potentially disrupts the automatic ACL From fa2cafe2eefb84e5af74e436e1ba187aa067abe0 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 9 Mar 2020 12:26:43 -0400 Subject: [PATCH 304/739] Update annotation docs --- values.yaml | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/values.yaml b/values.yaml index e62fd2b538..0ff57cbc36 100644 --- a/values.yaml +++ b/values.yaml @@ -240,14 +240,18 @@ server: # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ priorityClassName: "" - # Extra annotations to attach to the server pods - # This should be a multi-line string mapping directly to the a map of - # the annotations to apply to the server pods + # Extra annotations to attach to the server pods. + # This should be a multi-line YAML string. + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null service: - # This should be a multi-line string mapping directly to the a map of - # the annotations to apply to the server service + # Annotations to apply to the server service. + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null # extraEnvVars is a list of extra environment variables to set with the stateful set. These could be @@ -339,8 +343,9 @@ client: priorityClassName: "" # Extra annotations to attach to the client pods - # This should be a multi-line string mapping directly to the a map of - # the annotations to apply to the client pods + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null # extraEnvVars is a list of extra environment variables to set with the pod. These could be @@ -420,9 +425,13 @@ ui: service: enabled: true type: null - # This should be a multi-line string mapping directly to the a map of - # the annotations to apply to the UI service + + # Annotations to apply to the UI service. + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null + # Additional ServiceSpec values # This should be a multi-line string mapping directly to a Kubernetes # ServiceSpec object. @@ -790,7 +799,10 @@ meshGateway: # type: NodePort. nodePort: null - # Optional YAML string for additional annotations. + # Annotations to apply to the mesh gateway service. + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null # Optional YAML string that will be appended to the Service spec. @@ -857,7 +869,10 @@ meshGateway: # Optional priorityClassName. priorityClassName: "" - # Optional YAML string for additional annotations. + # Annotations to apply to the mesh gateway deployment. + # Example: + # annotations: | + # "annotation-key": "annotation-value" annotations: null # Control whether a test Pod manifest is generated when running helm template. From 74177c29f24903a53ae82eaac7e07f2198e113c4 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 12 Mar 2020 10:51:19 -0400 Subject: [PATCH 305/739] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 201a4ffc6f..7c687706e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.17.0 (Feb 21, 2020) + BREAKING CHANGES: * `consul-k8s` `v0.12.0`+ is now required. The chart is passing new flags that are only available in this version. From 5fd93fca01063f1a380da79a761df1dd384f22a8 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 3 Mar 2020 16:10:14 -0500 Subject: [PATCH 306/739] Support ACL replication. Suport creating an ACL replication token (for primary dcs) and referencing a pre-created ACL replication token (for secondary dcs). --- templates/server-acl-init-job.yaml | 47 +++++++--- templates/server-config-configmap.yaml | 3 + templates/server-statefulset.yaml | 10 ++ test/unit/server-acl-init-job.bats | 123 +++++++++++++++++++++++++ test/unit/server-configmap.bats | 47 ++++++++++ test/unit/server-statefulset.bats | 75 +++++++++++++++ values.yaml | 17 ++++ 7 files changed, 310 insertions(+), 12 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 546c7d2233..0091612ea4 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -32,18 +32,28 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init - {{- if .Values.global.tls.enabled }} + {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey)) }} volumes: - - name: consul-ca-cert - secret: - {{- if .Values.global.tls.caCert.secretName }} - secretName: {{ .Values.global.tls.caCert.secretName }} - {{- else }} - secretName: {{ template "consul.fullname" . }}-ca-cert - {{- end }} - items: - - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} - path: tls.crt + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + - name: acl-replication-token + secret: + secretName: {{ .Values.global.acls.replicationToken.secretName }} + items: + - key: {{ .Values.global.acls.replicationToken.secretKey }} + path: acl-replication-token + {{- end }} {{- end }} containers: - name: post-install-job @@ -53,11 +63,18 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - {{- if .Values.global.tls.enabled }} + {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey)) }} volumeMounts: + {{- if .Values.global.tls.enabled }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + - name: acl-replication-token + mountPath: /consul/acl/tokens + readOnly: true + {{- end }} {{- end }} command: - "/bin/sh" @@ -96,6 +113,12 @@ spec: {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -create-client-token=false \ {{- end }} + {{- if .Values.global.acls.createReplicationToken }} + -create-acl-replication-token=true \ + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + -acl-replication-token-file=/consul/acl/tokens/acl-replication-token \ + {{- end }} {{- if .Values.global.enableConsulNamespaces }} -enable-namespaces=true \ {{- /* syncCatalog must be enabled to set sync flags */}} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index e7c3f050aa..a4c4af6a97 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -20,6 +20,9 @@ data: "enabled": true, "default_policy": "deny", "down_policy": "extend-cache", + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + "enable_token_replication": true, + {{- end }} "enable_token_persistence": true } } diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index e20f52a707..652e83c855 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -110,6 +110,13 @@ spec: - name: CONSUL_CACERT value: /consul/tls/ca/tls.crt {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + - name: ACL_REPLICATION_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.global.acls.replicationToken.secretName | quote }} + key: {{ .Values.global.acls.replicationToken.secretKey | quote }} + {{- end }} {{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }} command: - "/bin/sh" @@ -154,6 +161,9 @@ spec: {{- if .Values.global.federation.enabled }} -hcl="connect { enable_mesh_gateway_wan_federation = true }" \ {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + -hcl="acl { tokens { agent = \"${ACL_REPLICATION_TOKEN}\", replication = \"${ACL_REPLICATION_TOKEN}\" } }" \ + {{- end }} {{- if .Values.ui.enabled }} -ui \ {{- end }} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 29150d45c0..ab7d98c52b 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -658,3 +658,126 @@ load _helpers yq 'any(contains("inject-k8s-namespace-mirroring-prefix"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.acls.createReplicationToken + +@test "serverACLInit/Job: -create-acl-replication-token is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-acl-replication-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: -create-acl-replication-token is true when acls.createReplicationToken is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.createReplicationToken=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-acl-replication-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.acls.replicationToken + +@test "serverACLInit/Job: -acl-replication-token-file is not set by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-replication-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -acl-replication-token-file is not set when acls.replicationToken.secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretName=name' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-replication-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -acl-replication-token-file is not set when acls.replicationToken.secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-replication-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -acl-replication-token-file is set when acls.replicationToken.secretKey and secretName are set" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretName=name' \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the -acl-replication-token-file flag is set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-acl-replication-token-file=/consul/acl/tokens/acl-replication-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume exists + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | map(select(.name == "acl-replication-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount exists + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | map(select(.name == "acl-replication-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index e4a26fe800..da4a13c2c0 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -165,3 +165,50 @@ load _helpers yq -r '.data["proxy-defaults-config.json"]' | yq -r '.config_entries.bootstrap[0].mesh_gateway.mode' | tee /dev/stderr) [ "${actual}" = "remote" ] } + +#-------------------------------------------------------------------- +# global.acls.replicationToken + +@test "server/ConfigMap: enable_token_replication is not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: enable_token_replication is not set when acls.replicationToken.secretName is set but secretKey is not" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretName=name' \ + . | tee /dev/stderr | + yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: enable_token_replication is not set when acls.replicationToken.secretKey is set but secretName is not" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr | + yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: enable_token_replication is set when acls.replicationToken.secretKey and secretName are set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-config-configmap.yaml \ + --set 'global.bootstrapACLs=true' \ + --set 'global.acls.replicationToken.secretName=name' \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr | + yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index b1e85626c6..477819989f 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -685,3 +685,78 @@ load _helpers yq '.spec.template.spec.containers[0].command | join(" ") | contains("connect { enable_mesh_gateway_wan_federation = true }")' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# global.acls.replicationToken + +@test "server/StatefulSet: acl replication token config is not set by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("ACL_REPLICATION_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the ACL_REPLICATION_TOKEN environment variable is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].env | map(select(.name == "ACL_REPLICATION_TOKEN")) | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: acl replication token config is not set when acls.replicationToken.secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.acls.replicationToken.secretName=name' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("ACL_REPLICATION_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the ACL_REPLICATION_TOKEN environment variable is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].env | map(select(.name == "ACL_REPLICATION_TOKEN")) | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: acl replication token config is not set when acls.replicationToken.secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("ACL_REPLICATION_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the ACL_REPLICATION_TOKEN environment variable is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].env | map(select(.name == "ACL_REPLICATION_TOKEN")) | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "server/StatefulSet: acl replication token config is set when acls.replicationToken.secretKey and secretName are set" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.acls.replicationToken.secretName=name' \ + --set 'global.acls.replicationToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the flag is set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-hcl=\"acl { tokens { agent = \\\"${ACL_REPLICATION_TOKEN}\\\", replication = \\\"${ACL_REPLICATION_TOKEN}\\\" } }\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the ACL_REPLICATION_TOKEN environment variable is set. + local actual=$(echo "$object" | + yq -r -c '.spec.template.spec.containers[0].env | map(select(.name == "ACL_REPLICATION_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = '[{"name":"ACL_REPLICATION_TOKEN","valueFrom":{"secretKeyRef":{"name":"name","key":"key"}}}]' ] +} diff --git a/values.yaml b/values.yaml index 80c7b4184e..4b45397f7f 100644 --- a/values.yaml +++ b/values.yaml @@ -156,6 +156,23 @@ global: # This setting must be true in both primary and secondary datacenters. enabled: false + # Configure ACLs. + acls: + # If true, an ACL token will be created that can be used in secondary + # datacenters for replication. This should only be set to true in the + # primary datacenter since the replication token must be created from that + # datacenter. + # In secondary datacenters, the secret will be imported from the primary + # datacenter and referenced via global.acls.replicationToken. + createReplicationToken: false + + # replicationToken references a secret containing the replication ACL token. + # This token will be used by secondary datacenters to perform ACL replication + # and create ACL tokens and policies + replicationToken: + secretName: null + secretKey: null + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From 02e9ff47c6a1edd4c1dcc2f39f00951bfc43f435 Mon Sep 17 00:00:00 2001 From: Andrea Scarpino Date: Fri, 13 Mar 2020 15:47:56 +0100 Subject: [PATCH 307/739] Fix compatibility with Go 1.14 Fixes #390 --- templates/client-daemonset.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 94e96fdf86..12c20fdbc2 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -173,7 +173,7 @@ spec: {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} -encrypt="${GOSSIP_KEY}" \ {{- end }} - {{- if (.Values.client.join) and (gt (len .Values.client.join) 0) }} + {{- if .Values.client.join }} {{- range $value := .Values.client.join }} -retry-join="{{ $value }}" \ {{- end }} From a8307cb14dd33839da86dab709b88b84dbfefa16 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 18 Mar 2020 09:38:45 -0700 Subject: [PATCH 308/739] Update changelog --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c687706e9..e21c558cb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ ## Unreleased +IMPROVEMENTS: + +* Allow setting your own certificate authority for Consul to Consul communication +(i.e. not Connect service to service communication) [[GH-346](https://github.com/hashicorp/consul-helm/pull/346)]. + To use, set: + ```yaml + global: + tls: + caCert: + secretName: null + secretKey: null + caKey: + secretName: null + secretKey: null + ``` + See `values.yaml` for more details. +* Allow setting custom annotations for Consul server service [[GH-376](https://github.com/hashicorp/consul-helm/pull/376)] + To use, set: + ```yaml + server: + service: + annotations: | + "annotation-key": "annotation-value" + ``` + +BUG FIXES: + +* Fix incompatibility with Helm 3.1.2. [[GH-390](https://github.com/hashicorp/consul-helm/issues/390)] +* Ensure the Consul Enterprise license gets applied, even if servers take a long time to come up. [[GH-348](https://github.com/hashicorp/consul-helm/pull/348)) + ## 0.17.0 (Feb 21, 2020) BREAKING CHANGES: From bceeba92a8c804ee8dcb8339a08e60a64baa2851 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 18 Mar 2020 09:40:39 -0700 Subject: [PATCH 309/739] Bump chart version --- Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index dc44a42125..a7165c2f9f 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.17.0 +version: 0.18.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: From 21ded2e497006422b72658f9d869bfebdeb8cb46 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 18 Mar 2020 09:59:35 -0700 Subject: [PATCH 310/739] Add release number --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e21c558cb9..2a8ee83817 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.18.0 (Mar 18, 2020) + IMPROVEMENTS: * Allow setting your own certificate authority for Consul to Consul communication From 0474f5d4288b1e6097886e3761a7042750c77652 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 16 Mar 2020 14:01:03 -0700 Subject: [PATCH 311/739] Add lifecycle-sidecar to mesh gateway When Consul clients in Kubernetes restart, they lose their registrations. This causes any mesh gateways to be deregistered. To solve this, we need to run a sidecar that ensures the service is always registered: a lifecycle-sidecar. For the lifecycle-sidecar to work, it needs a service.hcl service config file. This required adding an init container that writes this file and does the initial service registration. Since the init container is registering the service, the consul connect envoy -mesh-gateway command no longer needs the -register flag. --- templates/mesh-gateway-deployment.yaml | 169 ++++++-- test/unit/mesh-gateway-deployment.bats | 526 ++++++++++++++++++++----- 2 files changed, 557 insertions(+), 138 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index ea7d8d70ed..666f0beb2e 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -1,6 +1,7 @@ {{- if .Values.meshGateway.enabled }} {{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} {{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} +{{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} {{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}} {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} apiVersion: apps/v1 @@ -48,6 +49,9 @@ spec: volumes: - name: consul-bin emptyDir: {} + - name: consul-service + emptyDir: + medium: "Memory" {{- if .Values.global.tls.enabled }} - name: consul-ca-cert secret: @@ -79,21 +83,100 @@ spec: volumeMounts: - name: consul-bin mountPath: /consul-bin - {{- if .Values.global.bootstrapACLs }} - # Wait for secret containing acl token to be ready. - # Doesn't do anything with it but when the main container starts we - # know that it's been created. - - name: mesh-gateway-acl-init + # service-init registers the mesh gateway service. + - name: service-init image: {{ .Values.global.imageK8S }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} command: - "/bin/sh" - "-ec" - | - consul-k8s acl-init \ - -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" - {{- end }} + {{- if .Values.global.bootstrapACLs }} + consul-k8s acl-init \ + -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -init-type="sync" \ + -token-sink-file=/consul/service/acl-token + {{ end }} + + {{- if .Values.meshGateway.wanAddress.host }} + WAN_ADDR="{{ .Values.meshGateway.wanAddress.host }}" + {{- else if .Values.meshGateway.wanAddress.useNodeName }} + WAN_ADDR="${NODE_NAME}" + {{- else if .Values.meshGateway.wanAddress.useNodeIP }} + WAN_ADDR="${HOST_IP}" + {{- end }} + + cat > /consul/service/service.hcl << EOF + service { + kind = "mesh-gateway" + name = "{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}" + {{- if .Values.global.federation.enabled }} + meta { + consul-wan-federation = "1" + } + {{- end }} + port = {{ .Values.meshGateway.containerPort }} + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = {{ .Values.meshGateway.containerPort }} + } + lan_ipv4 { + address = "${POD_IP}" + port = {{ .Values.meshGateway.containerPort }} + } + wan { + address = "${WAN_ADDR}" + port = {{ .Values.meshGateway.wanAddress.port }} + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = {{ .Values.meshGateway.wanAddress.port }} + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:{{ .Values.meshGateway.containerPort }}" + deregister_critical_service_after = "6h" + } + ] + } + EOF + + consul services register \ + {{- if .Values.global.bootstrapACLs }} + -token-file=/consul/service/acl-token \ + {{- end }} + /consul/service/service.hcl + volumeMounts: + - name: consul-service + mountPath: /consul/service + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} containers: - name: mesh-gateway image: {{ .Values.meshGateway.imageEnvoy | quote }} @@ -145,29 +228,10 @@ spec: value: $(HOST_IP):8502 {{- end }} command: - # /bin/sh -c is needed so we can use the pod-specific environment - # variables. - - "/bin/sh" - - "-ec" - - | - exec /consul-bin/consul connect envoy \ - -mesh-gateway \ - -register \ - -address="${POD_IP}:{{ .Values.meshGateway.containerPort }}" \ - {{- if .Values.meshGateway.wanAddress.host }} - -wan-address="{{ .Values.meshGateway.wanAddress.host }}:{{ .Values.meshGateway.wanAddress.port }}" \ - {{- else if .Values.meshGateway.wanAddress.useNodeName }} - -wan-address="${NODE_NAME}:{{ .Values.meshGateway.wanAddress.port }}" \ - {{- else if .Values.meshGateway.wanAddress.useNodeIP }} - -wan-address="${HOST_IP}:{{ .Values.meshGateway.wanAddress.port }}" \ - {{- end }} - {{- if and .Values.meshGateway.consulServiceName }} - {{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end }} - -service={{ .Values.meshGateway.consulServiceName | quote }} \ - {{- end }} - {{- if .Values.global.federation.enabled }} - -expose-servers \ - {{- end }} + - /consul-bin/consul + - connect + - envoy + - -mesh-gateway {{- if .Values.meshGateway.enableHealthChecks }} livenessProbe: tcpSocket: @@ -197,6 +261,45 @@ spec: exec: command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""] + # lifecycle-sidecar ensures the mesh gateway is always registered with + # the local Consul agent, even if it loses the initial registration. + - name: lifecycle-sidecar + image: {{ .Values.global.imageK8S }} + volumeMounts: + - name: consul-service + mountPath: /consul/service + readOnly: true + {{- if .Values.global.tls.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + command: + - consul-k8s + - lifecycle-sidecar + - -service-config=/consul/service/service.hcl + - -consul-binary=/bin/consul + {{- if .Values.global.bootstrapACLs }} + - -token-file=/consul/service/acl-token + {{- end }} {{- if .Values.meshGateway.priorityClassName }} priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} {{- end }} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index f92ec1a602..fd6efc7b59 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -243,25 +243,6 @@ key2: value2' \ [ "${actual}" = "ClusterFirst" ] } -#-------------------------------------------------------------------- -# BootstrapACLs - -@test "meshGateway/Deployment: global.BootstrapACLs enabled creates init container and secret" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'global.bootstrapACLs=true' \ - . | tee /dev/stderr ) - local init_container=$(echo "${actual}" | yq -r '.spec.template.spec.initContainers[1].name' | tee /dev/stderr) - [ "${init_container}" = "mesh-gateway-acl-init" ] - - local secret=$(echo "${actual}" | yq -r '.spec.template.spec.containers[0].env[2].name' | tee /dev/stderr) - [ "${secret}" = "CONSUL_HTTP_TOKEN" ] -} - #-------------------------------------------------------------------- # envoyImage @@ -335,7 +316,6 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [ $(echo "$actual" | yq -r '.command | join(" ") | contains("-address=\"${POD_IP}:443\"")') = "true" ] [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "443" ] [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "443" ] [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "443" ] @@ -352,85 +332,11 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [ $(echo "$actual" | yq -r '.command | join(" ") | contains("-address=\"${POD_IP}:8443\"")') = "true" ] [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "8443" ] [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "8443" ] [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] } -#-------------------------------------------------------------------- -# wanAddress - -@test "meshGateway/Deployment: wanAddress.port defaults to 443" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'meshGateway.wanAddress.useNodeIP=true' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:443\"")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "meshGateway/Deployment: wanAddress uses NodeIP by default" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:443\"")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "meshGateway/Deployment: wanAddress.useNodeIP" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'meshGateway.wanAddress.useNodeIP=true' \ - --set 'meshGateway.wanAddress.port=4444' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${HOST_IP}:4444\"")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "meshGateway/Deployment: wanAddress.useNodeName" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'meshGateway.wanAddress.useNodeIP=false' \ - --set 'meshGateway.wanAddress.useNodeName=true' \ - --set 'meshGateway.wanAddress.port=4444' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"${NODE_NAME}:4444\"")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "meshGateway/Deployment: wanAddress.host" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'meshGateway.wanAddress.useNodeIP=false' \ - --set 'meshGateway.wanAddress.useNodeName=false' \ - --set 'meshGateway.wanAddress.host=myhost' \ - --set 'meshGateway.wanAddress.port=4444' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | join(" ") | contains("-wan-address=\"myhost:4444\"")' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - #-------------------------------------------------------------------- # consulServiceName @@ -460,7 +366,6 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) - [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ "-service=\"mesh-gateway\"" ]] [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"mesh-gateway\"' ]] } @@ -475,7 +380,6 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) - [[ $(echo "${actual}" | yq -r '.command[2]' ) =~ "-service=\"overridden\"" ]] [[ $(echo "${actual}" | yq -r '.lifecycle.preStop.exec.command' ) =~ '-id=\"overridden\"' ]] } @@ -655,10 +559,122 @@ key2: value2' \ [ "${actual}" = "key" ] } -#-------------------------------------------------------------------- -# global.federation.enabled +##-------------------------------------------------------------------- +## service-init init container + +@test "meshGateway/Deployment: service-init init container" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF -@test "meshGateway/Deployment: -expose-servers set when federation.enabled=true" { +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container with global.bootstrapACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s acl-init \ + -secret-name="release-name-consul-mesh-gateway-acl-token" \ + -k8s-namespace=default \ + -init-type="sync" \ + -token-sink-file=/consul/service/acl-token + +WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + -token-file=/consul/service/acl-token \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container with global.federation.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -666,18 +682,318 @@ key2: value2' \ --set 'connectInject.enabled=true' \ --set 'global.federation.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | join(" ") | contains("-expose-servers")' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + meta { + consul-wan-federation = "1" + } + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container containerPort and wanAddress.port can be changed" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.containerPort=8888' \ + --set 'meshGateway.wanAddress.port=9999' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 8888 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 8888 + } + lan_ipv4 { + address = "${POD_IP}" + port = 8888 + } + wan { + address = "${WAN_ADDR}" + port = 9999 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 9999 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8888" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.useNodeIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.useNodeIP=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] } +EOF -@test "meshGateway/Deployment: -expose-servers not set when federation.enabled=false" { +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.useNodeName" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'global.federation.enabled=false' \ + --set 'meshGateway.wanAddress.useNodeIP=false' \ + --set 'meshGateway.wanAddress.useNodeName=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | join(" ") | contains("-expose-servers")' | tee /dev/stderr) - [ "${actual}" = "false" ] + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${NODE_NAME}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.host" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.useNodeIP=false' \ + --set 'meshGateway.wanAddress.host=example.com' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="example.com" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container consulServiceName can be changed" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.consulServiceName=new-name' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='WAN_ADDR="${HOST_IP}" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "new-name" + port = 443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 443 + } + lan_ipv4 { + address = "${POD_IP}" + port = 443 + } + wan { + address = "${WAN_ADDR}" + port = 443 + } + wan_ipv4 { + address = "${WAN_ADDR}" + port = 443 + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] } From a14a6b76dc8bfbe69c3d0373e46312bdff3e7ef7 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 25 Mar 2020 11:32:44 -0700 Subject: [PATCH 312/739] Allow setting items for server.extraVolumes --- templates/server-statefulset.yaml | 7 +++++++ test/unit/server-statefulset.bats | 14 ++++++++++++++ values.yaml | 3 +++ 3 files changed, 24 insertions(+) diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index e20f52a707..67787c415a 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -81,6 +81,13 @@ spec: {{- else if (eq .type "secret") }} secretName: {{ .name }} {{- end }} + {{- with .items }} + items: + {{- range . }} + - key: {{.key}} + path: {{.path}} + {{- end }} + {{- end }} {{- end }} {{- if .Values.server.priorityClassName }} priorityClassName: {{ .Values.server.priorityClassName | quote }} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index b1e85626c6..87fba37a79 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -258,6 +258,20 @@ load _helpers [ "${actual}" = "1" ] } +@test "server/StatefulSet: adds extra secret volume with items" { + cd `chart_dir` + + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.extraVolumes[0].type=secret' \ + --set 'server.extraVolumes[0].name=foo' \ + --set 'server.extraVolumes[0].items[0].key=key' \ + --set 'server.extraVolumes[0].items[0].path=path' \ + . | tee /dev/stderr | + yq -c '.spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + [ "${actual}" = "{\"name\":\"userconfig-foo\",\"secret\":{\"secretName\":\"foo\",\"items\":[{\"key\":\"key\",\"path\":\"path\"}]}}" ] +} + #-------------------------------------------------------------------- # affinity diff --git a/values.yaml b/values.yaml index 80c7b4184e..12bfdeb3f0 100644 --- a/values.yaml +++ b/values.yaml @@ -219,6 +219,9 @@ server: # - type: secret (or "configMap") # name: my-secret # load: false # if true, will add to `-config-dir` to load by Consul + # items: # optional items array + # - key: key + # path: path # Affinity Settings # Commenting out or setting as empty the affinity variable, will allow From a69bee485672037242c7bf91855370205d3db4a1 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 17 Mar 2020 16:35:41 -0700 Subject: [PATCH 313/739] Automatically use LB addresses for mesh gateways Add support for using the external address of Kubernetes load balancer for the mesh gateway wan address. This change uses the new consul-k8s service-address command to get the address of the load balancer. It also removes meshGateway.wanAddress.{useNodeIP, useNodeName, host} config values in favour of meshGateway.wanAddress.{source, static}. The new source value allows selecting NodeIP, NodeName, Service or Static. This is more extensible than the previous boolean values. We also change the default containerPort to 8443 from 443 because that port can't be bound to on GKE. These are backwards incompatible changes. --- templates/mesh-gateway-clusterrole.yaml | 11 +- templates/mesh-gateway-deployment.yaml | 43 ++- test/unit/mesh-gateway-clusterrole.bats | 24 +- test/unit/mesh-gateway-deployment.bats | 375 +++++++++++++++++------- test/unit/mesh-gateway-service.bats | 18 +- values.yaml | 61 ++-- 6 files changed, 369 insertions(+), 163 deletions(-) diff --git a/templates/mesh-gateway-clusterrole.yaml b/templates/mesh-gateway-clusterrole.yaml index 33f4dad139..91092a64a1 100644 --- a/templates/mesh-gateway-clusterrole.yaml +++ b/templates/mesh-gateway-clusterrole.yaml @@ -9,7 +9,7 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway -{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} +{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -28,6 +28,15 @@ rules: verbs: - get {{- end }} +{{- if eq .Values.meshGateway.wanAddress.source "Service" }} + - apiGroups: [""] + resources: + - services + resourceNames: + - {{ template "consul.fullname" . }}-mesh-gateway + verbs: + - get + {{- end }} {{- else }} rules: [] {{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 666f0beb2e..9b0bffe801 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -116,12 +116,35 @@ spec: -token-sink-file=/consul/service/acl-token {{ end }} - {{- if .Values.meshGateway.wanAddress.host }} - WAN_ADDR="{{ .Values.meshGateway.wanAddress.host }}" - {{- else if .Values.meshGateway.wanAddress.useNodeName }} - WAN_ADDR="${NODE_NAME}" - {{- else if .Values.meshGateway.wanAddress.useNodeIP }} + {{- $source := .Values.meshGateway.wanAddress.source }} + {{- $serviceType := .Values.meshGateway.service.type }} + {{- if and (eq $source "Service") (not .Values.meshGateway.service.enabled) }}{{ fail "if meshGateway.wanAddress.source=Service then meshGateway.service.enabled must be set to true" }}{{ end }} + {{- if or (eq $source "NodeIP") (and (eq $source "Service") (eq $serviceType "NodePort")) }} WAN_ADDR="${HOST_IP}" + {{- else if eq $source "NodeName" }} + WAN_ADDR="${NODE_NAME}" + {{- else if and (eq $source "Service") (or (eq $serviceType "ClusterIP") (eq $serviceType "LoadBalancer")) }} + consul-k8s service-address \ + -k8s-namespace={{ .Release.Namespace }} \ + -name={{ template "consul.fullname" . }}-mesh-gateway \ + -output-file=address.txt + WAN_ADDR="$(cat address.txt)" + {{- else if eq $source "Static" }} + {{- if eq .Values.meshGateway.wanAddress.static "" }}{{ fail "if meshGateway.wanAddress.source=Static then meshGateway.wanAddress.static cannot be empty" }}{{ end }} + WAN_ADDR="{{ .Values.meshGateway.wanAddress.static }}" + {{- else }} + {{- fail "currently set meshGateway values for wanAddress.source and service.type are not supported" }} + {{- end }} + + {{- if eq $source "Service" }} + {{- if eq $serviceType "NodePort" }} + {{- if not .Values.meshGateway.service.nodePort }}{{ fail "if meshGateway.wanAddress.source=Service and meshGateway.service.type=NodePort, meshGateway.service.nodePort must be set" }}{{ end }} + WAN_PORT="{{ .Values.meshGateway.service.nodePort }}" + {{- else }} + WAN_PORT="{{ .Values.meshGateway.service.port }}" + {{- end }} + {{- else }} + WAN_PORT="{{ .Values.meshGateway.wanAddress.port }}" {{- end }} cat > /consul/service/service.hcl << EOF @@ -140,17 +163,9 @@ spec: address = "${POD_IP}" port = {{ .Values.meshGateway.containerPort }} } - lan_ipv4 { - address = "${POD_IP}" - port = {{ .Values.meshGateway.containerPort }} - } wan { address = "${WAN_ADDR}" - port = {{ .Values.meshGateway.wanAddress.port }} - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = {{ .Values.meshGateway.wanAddress.port }} + port = ${WAN_PORT} } } checks = [ diff --git a/test/unit/mesh-gateway-clusterrole.bats b/test/unit/mesh-gateway-clusterrole.bats index 1f3db8298e..7e9e4ab863 100644 --- a/test/unit/mesh-gateway-clusterrole.bats +++ b/test/unit/mesh-gateway-clusterrole.bats @@ -49,19 +49,34 @@ load _helpers [ "${actual}" = "secrets" ] } -@test "meshGateway/ClusterRole: rules is empty if no ACLs or PSPs" { +@test "meshGateway/ClusterRole: rules for meshGateway.wanAddress.source=Service" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=LoadBalancer' \ + --set 'meshGateway.wanAddress.source=Service' \ + . | tee /dev/stderr | + yq -r '.rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "services" ] +} + +@test "meshGateway/ClusterRole: rules is empty if no ACLs, PSPs and meshGateway.source != Service" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-clusterrole.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.wanAddress.source=NodeIP' \ + --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.rules' | tee /dev/stderr) [ "${actual}" = "[]" ] } -@test "meshGateway/ClusterRole: rules for both ACLs and PSPs" { +@test "meshGateway/ClusterRole: rules for ACLs, PSPs and mesh gateways" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrole.yaml \ @@ -70,7 +85,10 @@ load _helpers --set 'client.grpc=true' \ --set 'global.bootstrapACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=LoadBalancer' \ + --set 'meshGateway.wanAddress.source=Service' \ . | tee /dev/stderr | yq -r '.rules | length' | tee /dev/stderr) - [ "${actual}" = "2" ] + [ "${actual}" = "3" ] } diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index fd6efc7b59..38939c05b0 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -306,7 +306,7 @@ key2: value2' \ #-------------------------------------------------------------------- # containerPort -@test "meshGateway/Deployment: containerPort defaults to 443" { +@test "meshGateway/Deployment: containerPort defaults to 8443" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -316,9 +316,9 @@ key2: value2' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "443" ] - [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "443" ] - [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "443" ] + [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "8443" ] + [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "8443" ] + [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] } @test "meshGateway/Deployment: containerPort can be overridden" { @@ -328,13 +328,13 @@ key2: value2' \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'meshGateway.containerPort=8443' \ + --set 'meshGateway.containerPort=9443' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) - [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "8443" ] - [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "8443" ] - [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "8443" ] + [ $(echo "$actual" | yq -r '.ports[0].containerPort') = "9443" ] + [ $(echo "$actual" | yq -r '.livenessProbe.tcpSocket.port') = "9443" ] + [ $(echo "$actual" | yq -r '.readinessProbe.tcpSocket.port') = "9443" ] } #-------------------------------------------------------------------- @@ -571,37 +571,34 @@ key2: value2' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) - exp='WAN_ADDR="${HOST_IP}" + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" name = "mesh-gateway" - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -630,37 +627,34 @@ consul services register \ -init-type="sync" \ -token-sink-file=/consul/service/acl-token -WAN_ADDR="${HOST_IP}" +consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" name = "mesh-gateway" - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -684,7 +678,12 @@ consul services register \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) - exp='WAN_ADDR="${HOST_IP}" + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { @@ -693,31 +692,23 @@ service { meta { consul-wan-federation = "1" } - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -737,11 +728,13 @@ consul services register \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'meshGateway.containerPort=8888' \ + --set 'meshGateway.wanAddress.source=NodeIP' \ --set 'meshGateway.wanAddress.port=9999' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="${HOST_IP}" +WAN_PORT="9999" cat > /consul/service/service.hcl << EOF service { @@ -754,17 +747,9 @@ service { address = "${POD_IP}" port = 8888 } - lan_ipv4 { - address = "${POD_IP}" - port = 8888 - } wan { address = "${WAN_ADDR}" - port = 9999 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 9999 + port = ${WAN_PORT} } } checks = [ @@ -784,47 +769,40 @@ consul services register \ [ "${actual}" = "${exp}" ] } -@test "meshGateway/Deployment: service-init init container wanAddress.useNodeIP" { +@test "meshGateway/Deployment: service-init init container wanAddress.source=NodeIP" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'meshGateway.wanAddress.useNodeIP=true' \ + --set 'meshGateway.wanAddress.source=NodeIP' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="${HOST_IP}" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" name = "mesh-gateway" - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -837,48 +815,40 @@ consul services register \ [ "${actual}" = "${exp}" ] } -@test "meshGateway/Deployment: service-init init container wanAddress.useNodeName" { +@test "meshGateway/Deployment: service-init init container wanAddress.source=NodeName" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'meshGateway.wanAddress.useNodeIP=false' \ - --set 'meshGateway.wanAddress.useNodeName=true' \ + --set 'meshGateway.wanAddress.source=NodeName' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="${NODE_NAME}" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" name = "mesh-gateway" - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 - } - wan_ipv4 { - address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -891,48 +861,122 @@ consul services register \ [ "${actual}" = "${exp}" ] } -@test "meshGateway/Deployment: service-init init container wanAddress.host" { +@test "meshGateway/Deployment: service-init init container wanAddress.source=Static fails if wanAddress.static is empty" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.source=Static' \ + --set 'meshGateway.wanAddress.static=' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if meshGateway.wanAddress.source=Static then meshGateway.wanAddress.static cannot be empty" ]] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.source=Static" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'meshGateway.wanAddress.useNodeIP=false' \ - --set 'meshGateway.wanAddress.host=example.com' \ + --set 'meshGateway.wanAddress.source=Static' \ + --set 'meshGateway.wanAddress.static=example.com' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="example.com" +WAN_PORT="443" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" name = "mesh-gateway" - port = 443 + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 - } - lan_ipv4 { - address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.source=Service fails if service.enable is false" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.source=Service' \ + --set 'meshGateway.service.enabled=false' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if meshGateway.wanAddress.source=Service then meshGateway.service.enabled must be set to true" ]] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.source=Service, type=LoadBalancer" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.source=Service' \ + --set 'meshGateway.wanAddress.port=ignored' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 8443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 8443 } - wan_ipv4 { + wan { address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] @@ -945,47 +989,160 @@ consul services register \ [ "${actual}" = "${exp}" ] } -@test "meshGateway/Deployment: service-init init container consulServiceName can be changed" { +@test "meshGateway/Deployment: service-init init container wanAddress.source=Service, type=NodePort" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'meshGateway.consulServiceName=new-name' \ + --set 'meshGateway.wanAddress.source=Service' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.nodePort=9999' \ + --set 'meshGateway.service.type=NodePort' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="${HOST_IP}" +WAN_PORT="9999" cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" - name = "new-name" - port = 443 + name = "mesh-gateway" + port = 8443 address = "${POD_IP}" tagged_addresses { lan { address = "${POD_IP}" - port = 443 + port = 8443 + } + wan { + address = "${WAN_ADDR}" + port = ${WAN_PORT} } - lan_ipv4 { + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.source=Service, type=NodePort fails if service.nodePort is null" { + cd `chart_dir` + run helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.source=Service' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=NodePort' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if meshGateway.wanAddress.source=Service and meshGateway.service.type=NodePort, meshGateway.service.nodePort must be set" ]] +} + +@test "meshGateway/Deployment: service-init init container wanAddress.source=Service, type=ClusterIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.wanAddress.source=Service' \ + --set 'meshGateway.wanAddress.port=ignored' \ + --set 'meshGateway.service.enabled=true' \ + --set 'meshGateway.service.type=ClusterIP' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "mesh-gateway" + port = 8443 + address = "${POD_IP}" + tagged_addresses { + lan { address = "${POD_IP}" - port = 443 + port = 8443 } wan { address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} + } + } + checks = [ + { + name = "Mesh Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} +@test "meshGateway/Deployment: service-init init container consulServiceName can be changed" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'meshGateway.consulServiceName=new-name' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-mesh-gateway \ + -output-file=address.txt +WAN_ADDR="$(cat address.txt)" +WAN_PORT="443" + +cat > /consul/service/service.hcl << EOF +service { + kind = "mesh-gateway" + name = "new-name" + port = 8443 + address = "${POD_IP}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 8443 } - wan_ipv4 { + wan { address = "${WAN_ADDR}" - port = 443 + port = ${WAN_PORT} } } checks = [ { name = "Mesh Gateway Listening" interval = "10s" - tcp = "${POD_IP}:443" + tcp = "${POD_IP}:8443" deregister_critical_service_after = "6h" } ] diff --git a/test/unit/mesh-gateway-service.bats b/test/unit/mesh-gateway-service.bats index ac8a7c3ed3..a5f35eeb36 100755 --- a/test/unit/mesh-gateway-service.bats +++ b/test/unit/mesh-gateway-service.bats @@ -11,7 +11,7 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/Service: disabled by default with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/Service: enabled by default with meshGateway, connectInject and client.grpc enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-service.yaml \ @@ -20,7 +20,7 @@ load _helpers --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) - [ "${actual}" = "false" ] + [ "${actual}" = "true" ] } @test "meshGateway/Service: enabled with meshGateway.enabled=true meshGateway.service.enabled" { @@ -109,7 +109,7 @@ load _helpers --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.ports[0].targetPort' | tee /dev/stderr) - [ "${actual}" = "443" ] + [ "${actual}" = "8443" ] } @test "meshGateway/Service: uses targetPort from containerPort" { @@ -120,10 +120,10 @@ load _helpers --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ - --set 'meshGateway.containerPort=8443' \ + --set 'meshGateway.containerPort=9443' \ . | tee /dev/stderr | yq -r '.spec.ports[0].targetPort' | tee /dev/stderr) - [ "${actual}" = "8443" ] + [ "${actual}" = "9443" ] } #-------------------------------------------------------------------- @@ -159,7 +159,7 @@ load _helpers #-------------------------------------------------------------------- # Service type -@test "meshGateway/Service: defaults to type ClusterIP" { +@test "meshGateway/Service: defaults to type LoadBalancer" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-service.yaml \ @@ -169,7 +169,7 @@ load _helpers --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.type' | tee /dev/stderr) - [ "${actual}" = "ClusterIP" ] + [ "${actual}" = "LoadBalancer" ] } @test "meshGateway/Service: can set type" { @@ -180,10 +180,10 @@ load _helpers --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ - --set 'meshGateway.service.type=LoadBalancer' \ + --set 'meshGateway.service.type=ClusterIP' \ . | tee /dev/stderr | yq -r '.spec.type' | tee /dev/stderr) - [ "${actual}" = "LoadBalancer" ] + [ "${actual}" = "ClusterIP" ] } #-------------------------------------------------------------------- diff --git a/values.yaml b/values.yaml index 4b45397f7f..d754b6cbc7 100644 --- a/values.yaml +++ b/values.yaml @@ -766,46 +766,53 @@ meshGateway: # Number of replicas for the Deployment. replicas: 2 - # What gets registered as wan address for the gateway. + # What gets registered as WAN address for the gateway. wanAddress: - # Port that gets registered. + # source configures where to retrieve the WAN address (and possibly port) + # for the mesh gateway from. + # Can be set to either: Service, NodeIP, NodeName or Static. + # + # Service - Determine the address based on the service type. + # If service.type=LoadBalancer use the external IP or hostname of + # the service. Use the port set by service.port. + # If service.type=NodePort use the Node IP. The port will be set to + # service.nodePort so service.nodePort cannot be null. + # If service.type=ClusterIP use the ClusterIP. The port will be set to + # service.port. + # service.type=ExternalName is not supported. + # NodeIP - The node IP as provided by the Kubernetes downward API. + # NodeName - The name of the node as provided by the Kubernetes downward + # API. This is useful if the node names are DNS entries that + # are routable from other datacenters. + # Static - Use the address hardcoded in meshGateway.wanAddress.static. + source: "Service" + + # Port that gets registered for WAN traffic. + # If source is set to "Service" then this setting will have no effect. + # See the documentation for source as to which port will be used in that + # case. port: 443 - # If true, each Gateway Pod will advertise its NodeIP - # (as provided by the Kubernetes downward API) as the wan address. - # This is useful if the node IPs are routable from other DCs. - # useNodeName and host must be false and "" respectively. - useNodeIP: true - - # If true, each Gateway Pod will advertise its NodeName - # (as provided by the Kubernetes downward API) as the wan address. - # This is useful if the node names are DNS entries that are - # routable from other DCs. - # meshGateway.wanAddress.port will be used as the port for the wan address. - # useNodeIP and host must be false and "" respectively. - useNodeName: false - - # If set, each gateway Pod will use this host as its wan address. - # Users must ensure that this address routes to the Gateway pods, - # for example via a DNS entry that routes to the Service fronting the Deployment. - # meshGateway.wanAddress.port will be used as the port for the wan address. - # useNodeIP and useNodeName must be false. - host: "" + # If source is set to "Static" then this value will be used as the WAN + # address of the mesh gateways. This is useful if you've configured a + # DNS entry to point to your mesh gateways. + static: "" # The service option configures the Service that fronts the Gateway Deployment. service: # Whether to create a Service or not. - enabled: false + enabled: true # Type of service, ex. LoadBalancer, ClusterIP. - type: ClusterIP + type: LoadBalancer # Port that the service will be exposed on. # The targetPort will be set to meshGateway.containerPort. port: 443 - # Optional nodePort of the service. Can be used in conjunction with - # type: NodePort. + # Optionally hardcode the nodePort of the service if using type: NodePort. + # If not set and using type: NodePort, Kubernetes will automatically assign + # a port. nodePort: null # Optional YAML string for additional annotations. @@ -829,7 +836,7 @@ meshGateway: consulServiceName: "" # Port that the gateway will run on inside the container. - containerPort: 443 + containerPort: 8443 # Optional hostPort for the gateway to be exposed on. # This can be used with wanAddress.port and wanAddress.useNodeIP From ce92d48903fd526328815d302b97508c813f94c6 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 24 Mar 2020 13:03:27 -0700 Subject: [PATCH 314/739] Remove use of -init-type=sync as it has no effect As part of https://github.com/hashicorp/consul-k8s/pull/232 we removed the docs about -init-type=sync. If -init-type was set to sync it actually had no effect. Only -init-type=client had effect so this change stops setting that flag in the case of sync. --- templates/client-snapshot-agent-deployment.yaml | 3 +-- templates/connect-inject-deployment.yaml | 3 +-- templates/enterprise-license-job.yaml | 3 +-- templates/mesh-gateway-deployment.yaml | 1 - templates/sync-catalog-deployment.yaml | 3 +-- test/unit/mesh-gateway-deployment.bats | 1 - 6 files changed, 4 insertions(+), 10 deletions(-) diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index ec1cf52113..c7544b0133 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -126,8 +126,7 @@ spec: - | consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" + -k8s-namespace={{ .Release.Namespace }} volumeMounts: - name: aclconfig mountPath: /consul/aclconfig diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 29d9580157..fecb8d071a 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -190,8 +190,7 @@ spec: - | consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-connect-inject-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" + -k8s-namespace={{ .Release.Namespace }} {{- end }} {{- if .Values.connectInject.nodeSelector }} nodeSelector: diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index ddc6eff67d..71d9598f0a 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -109,8 +109,7 @@ spec: - | consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-enterprise-license-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" + -k8s-namespace={{ .Release.Namespace }} {{- end }} {{- end }} {{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 9b0bffe801..a593758c51 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -112,7 +112,6 @@ spec: consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" \ -token-sink-file=/consul/service/acl-token {{ end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 23cb7f1a14..468d1b3599 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -175,8 +175,7 @@ spec: - | consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-catalog-sync-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} \ - -init-type="sync" + -k8s-namespace={{ .Release.Namespace }} {{- end }} {{- if .Values.syncCatalog.nodeSelector }} nodeSelector: diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 38939c05b0..9680263e75 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -624,7 +624,6 @@ consul services register \ exp='consul-k8s acl-init \ -secret-name="release-name-consul-mesh-gateway-acl-token" \ -k8s-namespace=default \ - -init-type="sync" \ -token-sink-file=/consul/service/acl-token consul-k8s service-address \ From e892588288c5c14197306cc714aabb2473f6f59e Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 30 Mar 2020 11:03:44 -0700 Subject: [PATCH 315/739] Support auto-encrypt (#375) * Support auto-encrypt Setting the global.tls.enableAutoEncrypt will now enable auto-encrypt for clients and servers and switch consul-k8s components that need to talk to the clients (connect injector, mesh gateway, sync catalog, and snapshot agent) to now get the CA through the API from the Consul server before they start. Optionally, allow configuring external server information to be used for HTTPS API. Currently, this is only used to retrieve client's CA when using auto-encrypt, but it could potentially be extended for other use cases (e.g. ACL bootstrapping) when the Consul server cluster is outside of k8s. --- templates/_helpers.tpl | 41 +++++ templates/client-daemonset.yaml | 36 +++- .../client-snapshot-agent-deployment.yaml | 20 ++- templates/connect-inject-deployment.yaml | 35 ++-- templates/mesh-gateway-deployment.yaml | 14 ++ templates/server-statefulset.yaml | 7 +- templates/sync-catalog-deployment.yaml | 18 +- templates/tests/test-runner.yaml | 23 ++- test/unit/client-daemonset.bats | 118 +++++++++++-- .../client-snapshot-agent-deployment.bats | 66 ++++++++ test/unit/connect-inject-deployment.bats | 68 ++++++++ test/unit/helpers.bats | 158 ++++++++++++++++++ test/unit/mesh-gateway-deployment.bats | 58 +++++++ test/unit/server-statefulset.bats | 18 +- test/unit/sync-catalog-deployment.bats | 64 +++++++ values.yaml | 41 +++++ 16 files changed, 738 insertions(+), 47 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index fe11cdfee8..c0a43bdffe 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -61,3 +61,44 @@ Inject extra environment vars in the format key:value, if populated {{- end -}} {{- end -}} {{- end -}} + +{{/* +Get Consul client CA to use when auto-encrypt is enabled. +This template is for an init container. +*/}} +{{- define "consul.getAutoEncryptClientCA" -}} +- name: get-auto-encrypt-client-ca + image: {{ .Values.global.imageK8S }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s get-consul-client-ca \ + -output-file=/consul/tls/client/ca/tls.crt \ + {{- if .Values.externalServers.enabled }} + {{- if not (or .Values.externalServers.https.address .Values.client.join)}}{{ fail "either client.join or externalServers.https.address must be set if externalServers.enabled is true" }}{{ end -}} + {{- if .Values.externalServers.https.address }} + -server-addr={{ .Values.externalServers.https.address }} \ + {{- else }} + -server-addr={{ quote (first .Values.client.join) }} \ + {{- end }} + -server-port={{ .Values.externalServers.https.port }} \ + {{- if .Values.externalServers.https.tlsServerName }} + -tls-server-name={{ .Values.externalServers.https.tlsServerName }} \ + {{- end }} + {{- if not .Values.externalServers.https.useSystemRoots }} + -ca-file=/consul/tls/ca/tls.crt + {{- end }} + {{- else }} + -server-addr={{ template "consul.fullname" . }}-server \ + -server-port=8501 \ + -ca-file=/consul/tls/ca/tls.crt + {{- end }} + volumeMounts: + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + {{- end }} + - name: consul-auto-encrypt-ca-cert + mountPath: /consul/tls/client/ca +{{- end -}} \ No newline at end of file diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 0a82d3174c..0f0f1b961e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -78,6 +78,7 @@ spec: items: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt + {{ if not .Values.global.tls.enableAutoEncrypt }} - name: consul-ca-key secret: {{- if .Values.global.tls.caKey.secretName }} @@ -88,12 +89,13 @@ spec: items: - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} path: tls.key - - name: tls-client-cert + - name: consul-client-cert emptyDir: # We're using tmpfs here so that # client certs are not written to disk medium: "Memory" {{- end }} + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} {{ .type }}: @@ -129,6 +131,10 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} - name: GOSSIP_KEY valueFrom: @@ -139,9 +145,14 @@ spec: {{- if .Values.global.tls.enabled }} - name: CONSUL_HTTP_ADDR value: https://localhost:8501 + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: CONSUL_HTTP_SSL_VERIFY + value: false + {{- else }} - name: CONSUL_CACERT value: /consul/tls/ca/tls.crt {{- end }} + {{- end }} {{- include "consul.extraEnvironmentVars" .Values.client | nindent 12 }} command: - "/bin/sh" @@ -158,13 +169,20 @@ spec: -hcl='leave_on_terminate = true' \ {{- if .Values.global.tls.enabled }} -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ + {{- if .Values.global.tls.enableAutoEncrypt }} + -hcl='auto_encrypt = {tls = true}' \ + -hcl="auto_encrypt = {ip_san = [\"$HOST_IP\"]}" \ + {{- else }} -hcl='cert_file = "/consul/tls/client/tls.crt"' \ -hcl='key_file = "/consul/tls/client/tls.key"' \ + {{- end }} {{- if .Values.global.tls.verify }} - -hcl='verify_incoming_rpc = true' \ -hcl='verify_outgoing = true' \ + {{- if not .Values.global.tls.enableAutoEncrypt }} + -hcl='verify_incoming_rpc = true' \ -hcl='verify_server_hostname = true' \ {{- end }} + {{- end }} -hcl='ports { https = 8501 }' \ {{- if .Values.global.tls.httpsOnly }} -hcl='ports { http = -1 }' \ @@ -189,7 +207,7 @@ spec: {{- end }} {{- if .Values.client.join }} {{- range $value := .Values.client.join }} - -retry-join="{{ $value }}" \ + -retry-join={{ quote $value }} \ {{- end }} {{- else }} {{- if .Values.server.enabled }} @@ -208,10 +226,12 @@ spec: - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true - - name: tls-client-cert + {{- if not .Values.global.tls.enableAutoEncrypt }} + - name: consul-client-cert mountPath: /consul/tls/client readOnly: true {{- end }} + {{- end }} {{- range .Values.client.extraVolumes }} - name: userconfig-{{ .name }} readOnly: true @@ -267,7 +287,7 @@ spec: - | {{- if .Values.global.tls.enabled }} curl \ - --cacert /consul/tls/ca/tls.crt \ + -k \ https://127.0.0.1:8501/v1/status/leader \ {{- else }} curl http://127.0.0.1:8500/v1/status/leader \ @@ -277,7 +297,7 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} - {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled) }} + {{- if (or .Values.global.bootstrapACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} initContainers: {{- if .Values.global.bootstrapACLs }} - name: client-acl-init @@ -294,7 +314,7 @@ spec: - name: aclconfig mountPath: /consul/aclconfig {{- end }} - {{- if .Values.global.tls.enabled }} + {{- if and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt) }} - name: client-tls-init image: "{{ default .Values.global.image .Values.client.image }}" env: @@ -316,7 +336,7 @@ spec: mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0.pem tls.crt mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0-key.pem tls.key volumeMounts: - - name: tls-client-cert + - name: consul-client-cert mountPath: /consul/tls/client - name: consul-ca-cert mountPath: /consul/tls/ca/cert diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index ec1cf52113..0b33466d6e 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -52,6 +52,7 @@ spec: emptyDir: {} {{- end }} {{- if .Values.global.tls.enabled }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -63,6 +64,12 @@ spec: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} {{- end }} containers: - name: consul-snapshot-agent @@ -111,13 +118,18 @@ spec: mountPath: /consul/aclconfig {{- end }} {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt}} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true - {{- end }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- end }} + {{- if (or .Values.global.bootstrapACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} initContainers: + {{- if .Values.global.bootstrapACLs }} - name: client-snapshot-agent-acl-init image: {{ .Values.global.imageK8S }} command: @@ -132,6 +144,10 @@ spec: - name: aclconfig mountPath: /consul/aclconfig {{- end }} + {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} + {{- end }} + {{- end }} {{- if .Values.client.nodeSelector }} nodeSelector: {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 29d9580157..4081f50acd 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -41,6 +41,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + {{- if .Values.global.tls.enabled }} + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end }} {{- /* A Consul client and ACL token is only necessary for the connect injector if namespaces are enabled */}} {{- if .Values.global.enableConsulNamespaces }} - name: HOST_IP @@ -60,15 +64,12 @@ spec: name: "{{ template "consul.fullname" . }}-connect-inject-acl-token" key: "token" {{- end }} - {{- if .Values.global.tls.enabled }} - name: CONSUL_HTTP_ADDR + {{- if .Values.global.tls.enabled }} value: https://$(HOST_IP):8501 - - name: CONSUL_CACERT - value: /consul/tls/ca/tls.crt - {{- else }} - - name: CONSUL_HTTP_ADDR + {{- else }} value: http://$(HOST_IP):8500 - {{- end }} + {{- end }} {{- end }} command: - "/bin/sh" @@ -89,10 +90,6 @@ spec: {{- else if .Values.global.bootstrapACLs }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} - - {{- if .Values.global.tls.enabled }} - -consul-ca-cert=/consul/tls/ca/tls.crt \ - {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} -enable-central-config=true \ {{- end }} @@ -155,7 +152,11 @@ spec: readOnly: true {{- end }} {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true {{- end }} @@ -168,6 +169,7 @@ spec: secretName: {{ .Values.connectInject.certs.secretName }} {{- end }} {{- if .Values.global.tls.enabled }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -179,9 +181,16 @@ spec: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} {{- end }} - {{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} + {{- if or (and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: + {{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} - name: injector-acl-init image: {{ .Values.global.imageK8S }} command: @@ -193,6 +202,10 @@ spec: -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" {{- end }} + {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} + {{- end }} + {{- end }} {{- if .Values.connectInject.nodeSelector }} nodeSelector: {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index ff63e884d0..72e3e63efb 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -49,6 +49,7 @@ spec: - name: consul-bin emptyDir: {} {{- if .Values.global.tls.enabled }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -60,6 +61,12 @@ spec: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} {{- if .Values.meshGateway.hostNetwork }} hostNetwork: {{ .Values.meshGateway.hostNetwork }} {{- end }} @@ -79,6 +86,9 @@ spec: volumeMounts: - name: consul-bin mountPath: /consul-bin + {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" . | nindent 8 }} + {{- end }} {{- if .Values.global.bootstrapACLs }} # Wait for secret containing acl token to be ready. # Doesn't do anything with it but when the main container starts we @@ -105,7 +115,11 @@ spec: - name: consul-bin mountPath: /consul-bin {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true {{- end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index f51b49bfec..5107756f06 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -69,7 +69,7 @@ spec: items: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt - - name: tls-server-cert + - name: consul-server-cert secret: secretName: {{ template "consul.fullname" . }}-server-cert {{- end }} @@ -125,6 +125,9 @@ spec: -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ -hcl='cert_file = "/consul/tls/server/tls.crt"' \ -hcl='key_file = "/consul/tls/server/tls.key"' \ + {{- if .Values.global.tls.enableAutoEncrypt }} + -hcl='auto_encrypt = {allow_tls = true}' \ + {{- end }} {{- if .Values.global.tls.verify }} -hcl='verify_incoming_rpc = true' \ -hcl='verify_outgoing = true' \ @@ -167,7 +170,7 @@ spec: - name: consul-ca-cert mountPath: /consul/tls/ca/ readOnly: true - - name: tls-server-cert + - name: consul-server-cert mountPath: /consul/tls/server readOnly: true {{- end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 23cb7f1a14..4e100e38df 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -31,6 +31,7 @@ spec: serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog {{- if .Values.global.tls.enabled }} volumes: + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} @@ -42,6 +43,12 @@ spec: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} containers: - name: consul-sync-catalog image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" @@ -79,7 +86,11 @@ spec: {{- end }} {{- if .Values.global.tls.enabled }} volumeMounts: + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true {{- end }} @@ -165,8 +176,9 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 - {{- if .Values.global.bootstrapACLs }} + {{- if or .Values.global.bootstrapACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: + {{- if .Values.global.bootstrapACLs }} - name: sync-acl-init image: {{ .Values.global.imageK8S }} command: @@ -178,6 +190,10 @@ spec: -k8s-namespace={{ .Release.Namespace }} \ -init-type="sync" {{- end }} + {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} + {{- end }} + {{- end }} {{- if .Values.syncCatalog.nodeSelector }} nodeSelector: {{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }} diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 8f3388e739..cb2a5897ed 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -14,7 +14,8 @@ metadata: spec: {{- if .Values.global.tls.enabled }} volumes: - - name: tls-ca-cert + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} secretName: {{ .Values.global.tls.caCert.secretName }} @@ -24,6 +25,14 @@ spec: items: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt + {{- end }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- if and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt }} + initContainers: + {{- include "consul.getAutoEncryptClientCA" . | nindent 2 }} {{- end }} containers: - name: consul-test @@ -44,9 +53,15 @@ spec: {{- end }} {{- if .Values.global.tls.enabled }} volumeMounts: - - name: tls-ca-cert - mountPath: /consul/tls/ca - readOnly: true + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- else }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} {{- end }} command: - "/bin/sh" diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 6f13936002..d4739f7427 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -86,7 +86,6 @@ load _helpers [ "${actual}" = "true" ] } - #-------------------------------------------------------------------- # grpc @@ -424,7 +423,7 @@ load _helpers #-------------------------------------------------------------------- # global.tls.enabled -@test "client/DaemonSet: CA volume present when TLS is enabled" { +@test "client/DaemonSet: CA cert volume present when TLS is enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ @@ -434,13 +433,23 @@ load _helpers [ "${actual}" != "" ] } +@test "client/DaemonSet: CA key volume present when TLS is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-key")' | tee /dev/stderr) + [ "${actual}" != "" ] +} + @test "client/DaemonSet: client certificate volume present when TLS is enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes[] | select(.name == "tls-client-cert")' | tee /dev/stderr) + yq '.spec.template.spec.volumes[] | select(.name == "consul-client-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -506,13 +515,13 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: readiness checks use CA certificate when TLS is enabled" { +@test "client/DaemonSet: readiness checks skip TLS verification when TLS is enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("--cacert /consul/tls/ca/tls.crt")' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].readinessProbe.exec.command | join(" ") | contains("-k")' | tee /dev/stderr) [ "${actual}" = "true" ] } @@ -561,7 +570,7 @@ load _helpers @test "client/DaemonSet: sets Consul environment variables when global.tls.enabled" { cd `chart_dir` local env=$(helm template \ - -x templates/server-statefulset.yaml \ + -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) @@ -593,7 +602,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: doesn't set the verify_* flags by default when global.tls.enabled and global.tls.verify is false" { +@test "client/DaemonSet: doesn't set the verify_* flags when global.tls.enabled is true and global.tls.verify is false" { cd `chart_dir` local command=$(helm template \ -x templates/client-daemonset.yaml \ @@ -643,6 +652,89 @@ load _helpers [ "${actual}" = "key" ] } +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "client/DaemonSet: client certificate volume is not present when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-client-cert")' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "client/DaemonSet: sets auto_encrypt options for the client if auto-encrypt is enabled" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ")' | tee /dev/stderr) + + # enables auto encrypt on the client + actual=$(echo $command | jq -r '. | contains("auto_encrypt = {tls = true}")' | tee /dev/stderr) + [ "${actual}" == "true" ] + + # sets IP SANs to contain the HOST IP of the client + actual=$(echo $command | jq -r '. | contains("auto_encrypt = {ip_san = [\\\"$HOST_IP\\\"]}")' | tee /dev/stderr) + [ "${actual}" == "true" ] + + # doesn't set verify_incoming_rpc and verify_server_hostname + actual=$(echo $command | jq -r '. | contains("verify_incoming_rpc = true")' | tee /dev/stderr) + [ "${actual}" == "false" ] + + actual=$(echo $command | jq -r '. | contains("verify_server_hostname = true")' | tee /dev/stderr) + [ "${actual}" == "false" ] +} + +@test "client/DaemonSet: init container is not created when global.tls.enabled=true and global.tls.enableAutoEncrypt=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: CA key volume is not present when TLS is enabled and global.tls.enableAutoEncrypt=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-key")' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "client/DaemonSet: client certificate volume is not present when TLS is enabled and global.tls.enableAutoEncrypt=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-client-cert")' | tee /dev/stderr) + [ "${actual}" == "" ] +} + +@test "client/DaemonSet: sets CONSUL_HTTP_SSL_VERIFY environment variable to false when global.tls.enabled and global.tls.enableAutoEncrypt=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env[] | select(.name == "CONSUL_HTTP_SSL_VERIFY") | .value' | tee /dev/stderr) + [ "${actual}" == "false" ] +} + #-------------------------------------------------------------------- # extraEnvironmentVariables @@ -656,19 +748,11 @@ load _helpers yq -r '.spec.template.spec.containers[0].env' | tee /dev/stderr) local actual=$(echo $object | - yq -r '.[3].name' | tee /dev/stderr) - [ "${actual}" = "custom_proxy" ] - - local actual=$(echo $object | - yq -r '.[3].value' | tee /dev/stderr) + yq -r '.[] | select(.name=="custom_proxy").value' | tee /dev/stderr) [ "${actual}" = "fakeproxy" ] local actual=$(echo $object | - yq -r '.[4].name' | tee /dev/stderr) - [ "${actual}" = "no_proxy" ] - - local actual=$(echo $object | - yq -r '.[4].value' | tee /dev/stderr) + yq -r '.[] | select(.name=="no_proxy").value' | tee /dev/stderr) [ "${actual}" = "custom_no_proxy" ] } diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index 781664c89a..e0a6d251e9 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -269,3 +269,69 @@ load _helpers actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) [ "${actual}" = "key" ] } + +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "client/SnapshotAgentDeployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: adds both init containers when TLS with auto-encrypt and ACLs are enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers | length == 2' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/SnapshotAgentDeployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} \ No newline at end of file diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 0a34871ff9..be88d75fe7 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -433,6 +433,74 @@ load _helpers [ "${actual}" = "key" ] } +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "connectInject/Deployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: adds both init containers when TLS with auto-encrypt and ACLs + namespaces are enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers | length == 2' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} + #-------------------------------------------------------------------- # k8sAllowNamespaces & k8sDenyNamespaces diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 614e3fcbe5..94a7d258bf 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -100,3 +100,161 @@ load _helpers local actual=$(grep -r '{{ .Release.Name }}' templates/*.yaml | grep -v 'release: ' | tee /dev/stderr ) [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] } + + +#-------------------------------------------------------------------- +# consul.getAutoEncryptClientCA +# Similarly to consul.fullname tests, these tests use test-runner.yaml to test the +# consul.getAutoEncryptClientCA helper since we need an existing template that calls +# the consul.getAutoEncryptClientCA helper. + +@test "helper/consul.getAutoEncryptClientCA: get-auto-encrypt-client-ca uses server's stateful set address by default" { + cd `chart_dir` + local command=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) + + # check server address + actual=$(echo $command | jq ' . | contains("-server-addr=release-name-consul-server")') + [ "${actual}" = "true" ] + + # check server port + actual=$(echo $command | jq ' . | contains("-server-port=8501")') + [ "${actual}" = "true" ] + + # check server's CA cert + actual=$(echo $command | jq ' . | contains("-ca-file=/consul/tls/ca/tls.crt")') + [ "${actual}" = "true" ] +} + +@test "helper/consul.getAutoEncryptClientCA: uses client.join string if externalServers.enabled is true but the address is not provided" { + cd `chart_dir` + local command=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=consul-server.com' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) + + # check server address + actual=$(echo $command | jq ' . | contains("-server-addr=\"consul-server.com\"")') + [ "${actual}" = "true" ] + + # check the default server port is 443 if not provided + actual=$(echo $command | jq ' . | contains("-server-port=443")') + [ "${actual}" = "true" ] + + # check server's CA cert + actual=$(echo $command | jq ' . | contains("-ca-file=/consul/tls/ca/tls.crt")') + [ "${actual}" = "true" ] +} + +@test "helper/consul.getAutoEncryptClientCA: can set the provided server address if externalServers.enabled is true" { + cd `chart_dir` + local command=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=consul.io' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) + + # check server address + actual=$(echo $command | jq ' . | contains("-server-addr=consul.io")') + [ "${actual}" = "true" ] + + # check the default server port is 443 if not provided + actual=$(echo $command | jq ' . | contains("-server-port=443")') + [ "${actual}" = "true" ] + + # check server's CA cert + actual=$(echo $command | jq ' . | contains("-ca-file=/consul/tls/ca/tls.crt")') + [ "${actual}" = "true" ] +} + +@test "helper/consul.getAutoEncryptClientCA: fails if externalServers.enabled is true but neither client.join nor externalServers.https.address are provided" { + cd `chart_dir` + run helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "either client.join or externalServers.https.address must be set if externalServers.enabled is true" ]] +} + +@test "helper/consul.getAutoEncryptClientCA: can set the provided port if externalServers.enabled is true" { + cd `chart_dir` + local command=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=consul.io' \ + --set 'externalServers.https.port=8501' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) + + # check server address + actual=$(echo $command | jq ' . | contains("-server-addr=consul.io")') + [ "${actual}" = "true" ] + + # check the default server port is 443 if not provided + actual=$(echo $command | jq ' . | contains("-server-port=8501")') + [ "${actual}" = "true" ] + + # check server's CA cert + actual=$(echo $command | jq ' . | contains("-ca-file=/consul/tls/ca/tls.crt")') + [ "${actual}" = "true" ] +} + +@test "helper/consul.getAutoEncryptClientCA: can set TLS server name if externalServers.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=consul.io' \ + --set 'externalServers.https.tlsServerName=custom-server-name' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ") | contains("-tls-server-name=custom-server-name")' | tee /dev/stderr) + + [ "${actual}" = "true" ] +} + +@test "helper/consul.getAutoEncryptClientCA: doesn't provide the CA if externalServers.enabled is true and externalServers.useSystemRoots is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=consul.io' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ") | contains("-ca-file=/consul/tls/ca/tls.crt")' | tee /dev/stderr) + + [ "${actual}" = "false" ] +} + +@test "helper/consul.getAutoEncryptClientCA: doesn't mount the consul-ca-cert volume if externalServers.enabled is true and externalServers.useSystemRoots is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=consul.io' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").volumeMounts[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + [ "${actual}" = "" ] +} \ No newline at end of file diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 8523760de2..6cdf3daf97 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -654,3 +654,61 @@ key2: value2' \ actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) [ "${actual}" = "key" ] } + +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "meshGateway/Deployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} \ No newline at end of file diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index a4930e5039..a39ca8ae41 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -479,7 +479,7 @@ load _helpers -x templates/server-statefulset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes[] | select(.name == "tls-server-cert")' | tee /dev/stderr) + yq '.spec.template.spec.volumes[] | select(.name == "consul-server-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -499,7 +499,7 @@ load _helpers -x templates/server-statefulset.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "tls-server-cert")' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-server-cert")' | tee /dev/stderr) [ "${actual}" != "" ] } @@ -661,4 +661,18 @@ load _helpers # check that the volume uses the provided secret key actual=$(echo $ca_cert_volume | jq -r '.secret.items[0].key' | tee /dev/stderr) [ "${actual}" = "key" ] +} + +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "server/StatefulSet: enables auto-encrypt for the servers when global.tls.enableAutoEncrypt is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | join(" ") | contains("auto_encrypt = {allow_tls = true}")' | tee /dev/stderr) + [ "${actual}" = "true" ] } \ No newline at end of file diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index e486ceae3e..0205619664 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -439,6 +439,70 @@ load _helpers [ "${actual}" = "key" ] } +@test "syncCatalog/Deployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: adds both init containers when TLS with auto-encrypt and ACLs are enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.bootstrapACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers | length == 2' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} + #-------------------------------------------------------------------- # k8sAllowNamespaces & k8sDenyNamespaces diff --git a/values.yaml b/values.yaml index 0ff57cbc36..1285307e5b 100644 --- a/values.yaml +++ b/values.yaml @@ -88,6 +88,13 @@ global: tls: enabled: false + # enableAutoEncrypt turns on the auto-encrypt feature on + # clients and servers. + # It also switches consul-k8s components to retrieve the CA + # from the servers via the API. + # Requires Consul 1.7.1+ and consul-k8s 0.13.0 + enableAutoEncrypt: false + # serverAdditionalDNSSANs is a list of additional DNS names to # set as Subject Alternative Names (SANs) in the server certificate. # This is useful when you need to access the Consul server(s) externally, @@ -263,6 +270,40 @@ server: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com +# Add configuration for Consul servers running externally, +# i.e. outside of Kubernetes. +# This information is required if Consul servers are running +# outside of k8s and you’re setting global.tls.enableAutoEncrypt to true. +externalServers: + enabled: false + + # HTTPS configuration for external servers. + # Note: HTTP connections to the servers are + # not supported. + https: + # IP, DNS name, or Cloud auto-join string pointing to the external Consul servers. + # Note that if you’re providing the cloud auto-join string and multiple addresses + # can be returned, only the first address will be used. + # This value is required only if you would like to use + # a different server address from the one specified + # in the client.join property. + address: null + + # The HTTPS port of the server. + port: 443 + + # tlsServerName is the server name to use as the SNI + # host header when connecting with HTTPS. + # This property is useful in case ‘externalServers.https.address’ + # is not or can not be included in the server certificate’s SANs. + tlsServerName: null + + # If true, the Helm chart will ignore the CA set in + # global.tls.caCert and will rely on the container's + # system CAs for TLS verification when talking to Consul servers. + # Otherwise, the chart will use global.tls.caCert. + useSystemRoots: false + # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional # DC where a single agent is deployed per node. From fcdaa4fb90cf96c9cae0c13a8d5a9a6590fb25b9 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 2 Apr 2020 11:42:33 -0700 Subject: [PATCH 316/739] Use the auto-encrypt CA volume for service-init (#405) When auto-encrypt is enabled we need to use the volume with the client's CA rather than the server's. --- templates/client-daemonset.yaml | 2 +- templates/mesh-gateway-deployment.yaml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 0f0f1b961e..25c6e3a9de 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -147,7 +147,7 @@ spec: value: https://localhost:8501 {{- if .Values.global.tls.enableAutoEncrypt }} - name: CONSUL_HTTP_SSL_VERIFY - value: false + value: "false" {{- else }} - name: CONSUL_CACERT value: /consul/tls/ca/tls.crt diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 74c6601ba4..09f9225685 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -197,7 +197,11 @@ spec: - name: consul-service mountPath: /consul/service {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true {{- end }} @@ -298,7 +302,11 @@ spec: mountPath: /consul/service readOnly: true {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} - name: consul-ca-cert + {{- end }} mountPath: /consul/tls/ca readOnly: true {{- end }} From 0a98bb6066dc36adc9fd4bce591120b14baa7cb3 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 3 Apr 2020 11:50:53 -0700 Subject: [PATCH 317/739] Update CHANGELOG (#408) --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a8ee83817..dfab91a79f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ ## Unreleased +IMPROVEMENTS: + +* Support auto-encrypt [[GH-375](https://github.com/hashicorp/consul-helm/pull/375)]. + Auto-encrypt is the feature of Consul that allows clients to bootstrap their own certs + at startup. To enable it through the Helm Chart, set: + ```yaml + global: + tls: + enabled: true + enableAutoEncrypt: true + ``` + +FEATURES: + +* Add `externalServers` configuration to support configuring the Helm chart with Consul servers + running outside of a Kubernetes cluster [[GH-375](https://github.com/hashicorp/consul-helm/pull/375)]. At the moment, this configuration is only used together + with auto-encrypt, but might be extended later for other use-cases. + + To use auto-encrypt with external servers, you can set: + ```yaml + externalServers: + enabled: true + ``` + This will tell all consul-k8s components to talk to the external servers to retrieve + the clients' CA. Take a look at other properties you can set for `externalServers` + [here](https://github.com/hashicorp/consul-helm/blob/e892588288c5c14197306cc714aabb2473f6f59e/values.yaml#L273-L305). + ## 0.18.0 (Mar 18, 2020) IMPROVEMENTS: From 0d089f0ac6863024ae2b74eaddfcca75f7187c02 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 12 Mar 2020 12:36:09 -0400 Subject: [PATCH 318/739] Deprecate bootstrapACLs for acls.manageSystemACLs With the new global.acls setting, it was confusing to have bootstrapACLs as a separate setting. Instead we create a new global.acls.manageSystemACLs setting which can be used in place of global.bootstrapACLs. --- templates/NOTES.txt | 2 +- templates/client-clusterrole.yaml | 4 +- templates/client-daemonset.yaml | 10 +-- .../client-snapshot-agent-clusterrole.yaml | 9 +-- .../client-snapshot-agent-deployment.yaml | 16 ++-- ...connect-inject-authmethod-clusterrole.yaml | 2 +- ...-inject-authmethod-clusterrolebinding.yaml | 2 +- ...nect-inject-authmethod-serviceaccount.yaml | 2 +- templates/connect-inject-clusterrole.yaml | 2 +- templates/connect-inject-deployment.yaml | 10 +-- templates/enterprise-license-clusterrole.yaml | 4 +- templates/enterprise-license-job.yaml | 4 +- templates/mesh-gateway-clusterrole.yaml | 4 +- templates/mesh-gateway-deployment.yaml | 10 +-- .../server-acl-init-cleanup-clusterrole.yaml | 2 +- ...r-acl-init-cleanup-clusterrolebinding.yaml | 2 +- templates/server-acl-init-cleanup-job.yaml | 2 +- ...er-acl-init-cleanup-podsecuritypolicy.yaml | 2 +- ...erver-acl-init-cleanup-serviceaccount.yaml | 2 +- templates/server-acl-init-clusterrole.yaml | 2 +- .../server-acl-init-clusterrolebinding.yaml | 2 +- templates/server-acl-init-job.yaml | 2 +- .../server-acl-init-podsecuritypolicy.yaml | 2 +- templates/server-acl-init-serviceaccount.yaml | 2 +- templates/server-config-configmap.yaml | 2 +- templates/sync-catalog-clusterrole.yaml | 2 +- templates/sync-catalog-deployment.yaml | 8 +- test/unit/client-clusterrole.bats | 6 +- test/unit/client-daemonset.bats | 24 +++--- .../client-snapshot-agent-clusterrole.bats | 6 +- .../client-snapshot-agent-deployment.bats | 18 ++--- ...connect-inject-authmethod-clusterrole.bats | 6 +- ...-inject-authmethod-clusterrolebinding.bats | 6 +- ...nect-inject-authmethod-serviceaccount.bats | 6 +- test/unit/connect-inject-clusterrole.bats | 8 +- test/unit/connect-inject-deployment.bats | 26 +++---- test/unit/enterprise-license-clusterrole.bats | 8 +- test/unit/enterprise-license-job.bats | 10 +-- test/unit/helpers.bats | 24 +++++- test/unit/mesh-gateway-clusterrole.bats | 6 +- test/unit/mesh-gateway-deployment.bats | 14 ++-- .../server-acl-init-cleanup-clusterrole.bats | 14 ++-- ...r-acl-init-cleanup-clusterrolebinding.bats | 12 +-- test/unit/server-acl-init-cleanup-job.bats | 16 ++-- ...er-acl-init-cleanup-podsecuritypolicy.bats | 8 +- ...erver-acl-init-cleanup-serviceaccount.bats | 12 +-- test/unit/server-acl-init-clusterrole.bats | 16 ++-- .../server-acl-init-clusterrolebinding.bats | 12 +-- test/unit/server-acl-init-job.bats | 74 +++++++++---------- .../server-acl-init-podsecuritypolicy.bats | 8 +- test/unit/server-acl-init-serviceaccount.bats | 12 +-- test/unit/server-configmap.bats | 14 ++-- test/unit/sync-catalog-clusterrole.bats | 4 +- test/unit/sync-catalog-deployment.bats | 20 ++--- values.yaml | 32 ++++---- 55 files changed, 280 insertions(+), 255 deletions(-) diff --git a/templates/NOTES.txt b/templates/NOTES.txt index d7b2bde29e..beb6d943ba 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -20,7 +20,7 @@ To learn more about the release if you are using Helm 3, run: $ helm get all {{ .Release.Name }} -{{- if (and .Values.global.bootstrapACLs (gt (len .Values.server.extraConfig) 3)) }} +{{- if (and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (gt (len .Values.server.extraConfig) 3)) }} Warning: Defining server extraConfig potentially disrupts the automatic ACL bootstrapping required settings. This may cause future issues if there are conflicts. diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index f42afc9b20..abfc230ef7 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -8,7 +8,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies) }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -18,7 +18,7 @@ rules: verbs: - use {{- end }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - apiGroups: [""] resources: - secrets diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 0f0f1b961e..b84ad058a3 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -105,7 +105,7 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: aclconfig emptyDir: {} {{- end }} @@ -197,7 +197,7 @@ spec: -config-dir=/consul/userconfig/{{ .name }} \ {{- end }} {{- end }} - {{- if .Values.global.bootstrapACLs}} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -config-dir=/consul/aclconfig \ {{- end }} -datacenter={{ .Values.global.datacenter }} \ @@ -237,7 +237,7 @@ spec: readOnly: true mountPath: /consul/userconfig/{{ .name }} {{- end }} - {{- if .Values.global.bootstrapACLs}} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: aclconfig mountPath: /consul/aclconfig {{- end }} @@ -297,9 +297,9 @@ spec: resources: {{ tpl .Values.client.resources . | nindent 12 | trim }} {{- end }} - {{- if (or .Values.global.bootstrapACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} initContainers: - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: client-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/client-snapshot-agent-clusterrole.yaml b/templates/client-snapshot-agent-clusterrole.yaml index 0430b3e925..6307da5602 100644 --- a/templates/client-snapshot-agent-clusterrole.yaml +++ b/templates/client-snapshot-agent-clusterrole.yaml @@ -9,11 +9,8 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if not (or .Values.global.enablePodSecurityPolicies .Values.global.bootstrapACLs) }} -rules: [] -{{- else }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies) }} rules: -{{- end }} {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] resources: ["podsecuritypolicies"] @@ -22,7 +19,7 @@ rules: verbs: - use {{- end }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - apiGroups: [""] resources: - secrets @@ -32,5 +29,7 @@ rules: - get {{- end }} {{- else }} +rules: [] +{{- end }} {{- end }} {{- end }} diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index c46b13d4d6..9f01f8dab3 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -37,7 +37,7 @@ spec: {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} {{- end }} - {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} volumes: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config @@ -47,7 +47,7 @@ spec: - key: {{ .Values.client.snapshotAgent.configSecret.secretKey }} path: snapshot-config.json {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: aclconfig emptyDir: {} {{- end }} @@ -88,7 +88,7 @@ spec: - name: CONSUL_HTTP_ADDR value: http://$(HOST_IP):8500 {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -103,17 +103,17 @@ spec: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} -config-dir=/consul/config \ {{- end }} - {{- if .Values.global.bootstrapACLs}} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -config-dir=/consul/aclconfig \ {{- end }} - {{- if (or .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} volumeMounts: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config readOnly: true mountPath: /consul/config {{- end }} - {{- if .Values.global.bootstrapACLs}} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: aclconfig mountPath: /consul/aclconfig {{- end }} @@ -127,9 +127,9 @@ spec: readOnly: true {{- end }} {{- end }} - {{- if (or .Values.global.bootstrapACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} + {{- if (or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} initContainers: - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: client-snapshot-agent-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/connect-inject-authmethod-clusterrole.yaml b/templates/connect-inject-authmethod-clusterrole.yaml index 07a295b898..0d51693bbc 100644 --- a/templates/connect-inject-authmethod-clusterrole.yaml +++ b/templates/connect-inject-authmethod-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/connect-inject-authmethod-clusterrolebinding.yaml b/templates/connect-inject-authmethod-clusterrolebinding.yaml index d88df03305..5edc851897 100644 --- a/templates/connect-inject-authmethod-clusterrolebinding.yaml +++ b/templates/connect-inject-authmethod-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/connect-inject-authmethod-serviceaccount.yaml b/templates/connect-inject-authmethod-serviceaccount.yaml index e9c91d7929..b4a9b2c8ed 100644 --- a/templates/connect-inject-authmethod-serviceaccount.yaml +++ b/templates/connect-inject-authmethod-serviceaccount.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 158eaea2fe..6b809f039f 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -25,7 +25,7 @@ rules: verbs: - use {{- end }} -{{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} +{{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces }} - apiGroups: [""] resources: - secrets diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index e15d32af31..420f950a14 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -57,7 +57,7 @@ spec: secretKeyRef: name: {{ .Values.connectInject.aclInjectToken.secretName }} key: {{ .Values.connectInject.aclInjectToken.secretKey }} - {{- else if .Values.global.bootstrapACLs }} + {{- else if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -87,7 +87,7 @@ spec: -listen=:8080 \ {{- if .Values.connectInject.overrideAuthMethodName }} -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ - {{- else if .Values.global.bootstrapACLs }} + {{- else if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} @@ -113,7 +113,7 @@ spec: -k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ {{- end }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -consul-cross-namespace-acl-policy=cross-namespace-policy \ {{- end }} {{- end }} @@ -188,9 +188,9 @@ spec: {{- end }} {{- end }} {{- end }} - {{- if or (and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- if or (and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: - {{- if and .Values.global.bootstrapACLs .Values.global.enableConsulNamespaces }} + {{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces }} - name: injector-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-clusterrole.yaml index e3078a41ad..57197b3808 100644 --- a/templates/enterprise-license-clusterrole.yaml +++ b/templates/enterprise-license-clusterrole.yaml @@ -9,9 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} +{{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} rules: -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - apiGroups: [""] resources: - secrets diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 71d9598f0a..7d910c039f 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -65,7 +65,7 @@ spec: - name: CONSUL_CACERT value: /consul/tls/ca/tls.crt {{- end}} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -99,7 +99,7 @@ spec: mountPath: /consul/tls/ca readOnly: true {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} initContainers: - name: ent-license-acl-init image: {{ .Values.global.imageK8S }} diff --git a/templates/mesh-gateway-clusterrole.yaml b/templates/mesh-gateway-clusterrole.yaml index 91092a64a1..35ba5ac967 100644 --- a/templates/mesh-gateway-clusterrole.yaml +++ b/templates/mesh-gateway-clusterrole.yaml @@ -9,7 +9,7 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway -{{- if or .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} +{{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -19,7 +19,7 @@ rules: verbs: - use {{- end }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - apiGroups: [""] resources: - secrets diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 74c6601ba4..35aabad82f 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -1,7 +1,7 @@ {{- if .Values.meshGateway.enabled }} {{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} {{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} -{{- if and .Values.global.bootstrapACLs (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} +{{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.acls.manageSystemACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} {{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}} {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} apiVersion: apps/v1 @@ -118,7 +118,7 @@ spec: - "/bin/sh" - "-ec" - | - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ @@ -189,7 +189,7 @@ spec: EOF consul services register \ - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -token-file=/consul/service/acl-token \ {{- end }} /consul/service/service.hcl @@ -235,7 +235,7 @@ spec: fieldRef: fieldPath: spec.nodeName {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -325,7 +325,7 @@ spec: - lifecycle-sidecar - -service-config=/consul/service/service.hcl - -consul-binary=/bin/consul - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - -token-file=/consul/service/acl-token {{- end }} {{- if .Values.meshGateway.priorityClassName }} diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index d70db13c31..5c03ccc70a 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml index 789b5526a2..197d8b85b4 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index 11617fbe5a..d8f04cd232 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* See reason for this in server-acl-init-job.yaml */ -}} {{- if eq (int .Values.server.updatePartition) 0 }} # This job deletes the server-acl-init job once it completes successfully. diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml index 300ff20f23..52dcbd1291 100644 --- a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index 79b1d5c661..82b73865f2 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 15c14ba724..b4a0216971 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index 620a01ae59..1502550204 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 0091612ea4..bf3d441e34 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* We don't render this job when server.updatePartition > 0 because that means a server rollout is in progress and this job won't complete unless the rollout is finished (which won't happen until the partition is 0). diff --git a/templates/server-acl-init-podsecuritypolicy.yaml b/templates/server-acl-init-podsecuritypolicy.yaml index d39e06f344..003e06cbc7 100644 --- a/templates/server-acl-init-podsecuritypolicy.yaml +++ b/templates/server-acl-init-podsecuritypolicy.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index 7c0564367c..745ddd55b6 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -1,5 +1,5 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index a4c4af6a97..87a787c969 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -13,7 +13,7 @@ metadata: data: extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} acl-config.json: |- { "acl": { diff --git a/templates/sync-catalog-clusterrole.yaml b/templates/sync-catalog-clusterrole.yaml index fe0ed62a18..ccec8e65a9 100644 --- a/templates/sync-catalog-clusterrole.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -29,7 +29,7 @@ rules: - nodes verbs: - get -{{- if .Values.global.bootstrapACLs }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - apiGroups: [""] resources: - secrets diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index ebb86787c6..ff00f30e34 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -68,7 +68,7 @@ spec: name: {{ .Values.syncCatalog.aclSyncToken.secretName }} key: {{ .Values.syncCatalog.aclSyncToken.secretKey }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -152,7 +152,7 @@ spec: -k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ {{- end }} {{- end }} - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -consul-cross-namespace-acl-policy=cross-namespace-policy \ {{- end }} {{- end }} @@ -176,9 +176,9 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 - {{- if or .Values.global.bootstrapACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- if or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: - {{- if .Values.global.bootstrapACLs }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - name: sync-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-clusterrole.bats index 3519e70485..1a7e95d377 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-clusterrole.bats @@ -78,14 +78,14 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs @test "client/ClusterRole: allows secret access with global.bootsrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-clusterrole.yaml \ --set 'client.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules[0].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] @@ -96,7 +96,7 @@ load _helpers local actual=$(helm template \ -x templates/client-clusterrole.yaml \ --set 'client.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules[1].resources[0]' | tee /dev/stderr) diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index d4739f7427..d17ee62383 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -546,12 +546,12 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: both ACL and TLS init containers are created when global.tls.enabled=true and global.bootstrapACLs=true" { +@test "client/DaemonSet: both ACL and TLS init containers are created when global.tls.enabled=true and global.acls.manageSystemACLs=true" { cd `chart_dir` local has_acl_init_container=$(helm template \ -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init") | length > 0' | tee /dev/stderr) @@ -560,7 +560,7 @@ load _helpers local has_tls_init_container=$(helm template \ -x templates/client-daemonset.yaml \ --set 'global.tls.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init") | length > 0' | tee /dev/stderr) @@ -757,23 +757,23 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs -@test "client/DaemonSet: aclconfig volume is created when global.bootstrapACLs=true" { +@test "client/DaemonSet: aclconfig volume is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes[2].name == "aclconfig"' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/DaemonSet: aclconfig volumeMount is created when global.bootstrapACLs=true" { +@test "client/DaemonSet: aclconfig volumeMount is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].volumeMounts[2]' | tee /dev/stderr) @@ -786,21 +786,21 @@ load _helpers [ "${actual}" = "/consul/aclconfig" ] } -@test "client/DaemonSet: command includes aclconfig dir when global.bootstrapACLs=true" { +@test "client/DaemonSet: command includes aclconfig dir when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("/consul/aclconfig"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/DaemonSet: init container is created when global.bootstrapACLs=true" { +@test "client/DaemonSet: init container is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init")' | tee /dev/stderr) diff --git a/test/unit/client-snapshot-agent-clusterrole.bats b/test/unit/client-snapshot-agent-clusterrole.bats index 25fe077220..72613eaa61 100644 --- a/test/unit/client-snapshot-agent-clusterrole.bats +++ b/test/unit/client-snapshot-agent-clusterrole.bats @@ -59,7 +59,7 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs @test "client/SnapshotAgentClusterRole: allows secret access with global.bootsrapACLs=true" { cd `chart_dir` @@ -67,7 +67,7 @@ load _helpers -x templates/client-snapshot-agent-clusterrole.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'client.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules[0].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] @@ -79,7 +79,7 @@ load _helpers -x templates/client-snapshot-agent-clusterrole.yaml \ --set 'client.enabled=true' \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules[1].resources[0]' | tee /dev/stderr) diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index e0a6d251e9..4f71df03ad 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -92,7 +92,7 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs and snapshotAgent.configSecret +# global.acls.manageSystemACLs and snapshotAgent.configSecret @test "client/SnapshotAgentDeployment: no initContainer by default" { cd `chart_dir` @@ -104,12 +104,12 @@ load _helpers [ "${actual}" = "null" ] } -@test "client/SnapshotAgentDeployment: populates initContainer when global.bootstrapACLs=true" { +@test "client/SnapshotAgentDeployment: populates initContainer when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -125,12 +125,12 @@ load _helpers [ "${actual}" = "null" ] } -@test "client/SnapshotAgentDeployment: populates volumes when global.bootstrapACLs=true" { +@test "client/SnapshotAgentDeployment: populates volumes when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -158,12 +158,12 @@ load _helpers [ "${actual}" = "null" ] } -@test "client/SnapshotAgentDeployment: populates container volumeMounts when global.bootstrapACLs=true" { +@test "client/SnapshotAgentDeployment: populates container volumeMounts when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -314,7 +314,7 @@ load _helpers local actual=$(helm template \ -x templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ . | tee /dev/stderr | @@ -334,4 +334,4 @@ load _helpers . | tee /dev/stderr | yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] -} \ No newline at end of file +} diff --git a/test/unit/connect-inject-authmethod-clusterrole.bats b/test/unit/connect-inject-authmethod-clusterrole.bats index e7427e3793..ef144a8781 100644 --- a/test/unit/connect-inject-authmethod-clusterrole.bats +++ b/test/unit/connect-inject-authmethod-clusterrole.bats @@ -18,7 +18,7 @@ load _helpers --set 'global.enabled=false' \ --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -34,12 +34,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInjectAuthMethod/ClusterRole: enabled with global.bootstrapACLs.enabled=true" { +@test "connectInjectAuthMethod/ClusterRole: enabled with global.acls.manageSystemACLs.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-authmethod-clusterrole.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/connect-inject-authmethod-clusterrolebinding.bats b/test/unit/connect-inject-authmethod-clusterrolebinding.bats index 7375da3a0e..20952592db 100644 --- a/test/unit/connect-inject-authmethod-clusterrolebinding.bats +++ b/test/unit/connect-inject-authmethod-clusterrolebinding.bats @@ -18,7 +18,7 @@ load _helpers --set 'global.enabled=false' \ --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -34,12 +34,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInjectAuthMethod/ClusterRoleBinding: enabled with global.bootstrapACLs.enabled=true" { +@test "connectInjectAuthMethod/ClusterRoleBinding: enabled with global.acls.manageSystemACLs.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-authmethod-clusterrolebinding.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/connect-inject-authmethod-serviceaccount.bats b/test/unit/connect-inject-authmethod-serviceaccount.bats index e2b8d63b3e..e84627856f 100644 --- a/test/unit/connect-inject-authmethod-serviceaccount.bats +++ b/test/unit/connect-inject-authmethod-serviceaccount.bats @@ -18,7 +18,7 @@ load _helpers --set 'global.enabled=false' \ --set 'client.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -34,12 +34,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInjectAuthMethod/ServiceAccount: enabled with global.bootstrapACLs.enabled=true" { +@test "connectInjectAuthMethod/ServiceAccount: enabled with global.acls.manageSystemACLs.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-authmethod-serviceaccount.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/connect-inject-clusterrole.bats b/test/unit/connect-inject-clusterrole.bats index df66a8d32f..3281903c65 100644 --- a/test/unit/connect-inject-clusterrole.bats +++ b/test/unit/connect-inject-clusterrole.bats @@ -80,14 +80,14 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs for namespaces +# global.acls.manageSystemACLs for namespaces @test "connectInject/ClusterRole: does not allow secret access with global.bootsrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules | length' | tee /dev/stderr) [ "${actual}" = "1" ] @@ -98,7 +98,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ . | tee /dev/stderr | yq -r '.rules[1].resources[0]' | tee /dev/stderr) @@ -110,7 +110,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-clusterrole.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ --set 'global.enableConsulNamespaces=true' \ . | tee /dev/stderr | diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index be88d75fe7..9a14e0781d 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -327,12 +327,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/Deployment: -acl-auth-method is set when global.bootstrapACLs is true" { +@test "connectInject/Deployment: -acl-auth-method is set when global.acls.manageSystemACLs is true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"release-name-consul-k8s-auth-method\""))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -349,12 +349,12 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/Deployment: -acl-auth-method is overridden by connectInject.overrideAuthMethodName if global.bootstrapACLs is true" { +@test "connectInject/Deployment: -acl-auth-method is overridden by connectInject.overrideAuthMethodName if global.acls.manageSystemACLs is true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'connectInject.overrideAuthMethodName=override' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-acl-auth-method=\"override\""))' | tee /dev/stderr) @@ -477,7 +477,7 @@ load _helpers local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ @@ -720,15 +720,15 @@ load _helpers } #-------------------------------------------------------------------- -# namespaces + global.bootstrapACLs +# namespaces + global.acls.manageSystemACLs -@test "connectInject/Deployment: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { +@test "connectInject/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ --set 'global.enableConsulNamespaces=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '[.spec.template.spec.containers[0].env[].name] ' | tee /dev/stderr) @@ -741,13 +741,13 @@ load _helpers [ "${actual}" = "1" ] } -@test "connectInject/Deployment: init container is created when global.bootstrapACLs=true" { +@test "connectInject/Deployment: init container is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ --set 'global.enableConsulNamespaces=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) @@ -760,7 +760,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/Deployment: cross namespace policy is not added when global.bootstrapACLs=false" { +@test "connectInject/Deployment: cross namespace policy is not added when global.acls.manageSystemACLs=false" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ @@ -771,13 +771,13 @@ load _helpers [ "${actual}" = "false" ] } -@test "connectInject/Deployment: cross namespace policy is added when global.bootstrapACLs=true" { +@test "connectInject/Deployment: cross namespace policy is added when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ --set 'connectInject.enabled=true' \ --set 'global.enableConsulNamespaces=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/enterprise-license-clusterrole.bats b/test/unit/enterprise-license-clusterrole.bats index 4f02d3ecb3..b4ac2f7dd2 100644 --- a/test/unit/enterprise-license-clusterrole.bats +++ b/test/unit/enterprise-license-clusterrole.bats @@ -54,7 +54,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "enterpriseLicense/ClusterRole: rules are empty if global.bootstrapACLs and global.enablePodSecurityPolicies are false" { +@test "enterpriseLicense/ClusterRole: rules are empty if global.acls.manageSystemACLs and global.enablePodSecurityPolicies are false" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ @@ -66,15 +66,15 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs -@test "enterpriseLicense/ClusterRole: allows acl token when global.bootstrapACLs is true" { +@test "enterpriseLicense/ClusterRole: allows acl token when global.acls.manageSystemACLs is true" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-clusterrole.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules | map(select(.resourceNames[0] == "release-name-consul-enterprise-license-acl-token")) | length' | tee /dev/stderr) [ "${actual}" = "1" ] diff --git a/test/unit/enterprise-license-job.bats b/test/unit/enterprise-license-job.bats index 3a8ce55af2..9d66059a7c 100644 --- a/test/unit/enterprise-license-job.bats +++ b/test/unit/enterprise-license-job.bats @@ -55,27 +55,27 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs -@test "server/EnterpriseLicense: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { +@test "server/EnterpriseLicense: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "server/EnterpriseLicense: init container is created when global.bootstrapACLs=true" { +@test "server/EnterpriseLicense: init container is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/enterprise-license-job.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 94a7d258bf..80e3c3def2 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -87,6 +87,9 @@ load _helpers [ "${actual}" = "release-name-override-test" ] } +#-------------------------------------------------------------------- +# template consul.fullname +# # This test ensures that we use {{ template "consul.fullname" }} everywhere instead of # {{ .Release.Name }} because that's required in order to support the name # override settings fullnameOverride and global.name. In some cases, we need to @@ -101,7 +104,6 @@ load _helpers [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] } - #-------------------------------------------------------------------- # consul.getAutoEncryptClientCA # Similarly to consul.fullname tests, these tests use test-runner.yaml to test the @@ -257,4 +259,22 @@ load _helpers yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").volumeMounts[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# bootstrapACLs deprecation +# +# Test that every place global.bootstrapACLs is used, global.acls.manageSystemACLs +# is also used. +# If this test is failing, you've used either only global.bootstrapACLs or +# only global.acls.manageSystemACLs instead of using the backwards compatible: +# or global.acls.manageSystemACLs global.bootstrapACLs +@test "helper/bootstrapACLs: used alongside manageSystemACLs" { + cd `chart_dir` + + diff=$(diff <(grep -r '\.Values\.global\.bootstrapACLs' templates/*) <(grep -r 'or \.Values\.global\.acls\.manageSystemACLs \.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) + [ "$diff" = "" ] + + diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r 'or \.Values\.global\.acls\.manageSystemACLs \.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) + [ "$diff" = "" ] +} diff --git a/test/unit/mesh-gateway-clusterrole.bats b/test/unit/mesh-gateway-clusterrole.bats index 7e9e4ab863..988e22bcd3 100644 --- a/test/unit/mesh-gateway-clusterrole.bats +++ b/test/unit/mesh-gateway-clusterrole.bats @@ -36,14 +36,14 @@ load _helpers [ "${actual}" = "podsecuritypolicies" ] } -@test "meshGateway/ClusterRole: rules for global.bootstrapACLs=true" { +@test "meshGateway/ClusterRole: rules for global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules[0].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] @@ -83,7 +83,7 @@ load _helpers --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.type=LoadBalancer' \ diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 3cf61ddc1e..d2ccc861d3 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -340,7 +340,7 @@ key2: value2' \ #-------------------------------------------------------------------- # consulServiceName -@test "meshGateway/Deployment: fails if consulServiceName is set and bootstrapACLs is true" { +@test "meshGateway/Deployment: fails if consulServiceName is set and acls.manageSystemACLs is true" { cd `chart_dir` run helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -348,13 +348,13 @@ key2: value2' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ --set 'meshGateway.consulServiceName=override' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . [ "$status" -eq 1 ] - [[ "$output" =~ "if global.bootstrapACLs is true, meshGateway.consulServiceName cannot be set" ]] + [[ "$output" =~ "if global.acls.manageSystemACLs is true, meshGateway.consulServiceName cannot be set" ]] } -@test "meshGateway/Deployment: does not fail if consulServiceName is set to mesh-gateway and bootstrapACLs is true" { +@test "meshGateway/Deployment: does not fail if consulServiceName is set to mesh-gateway and acls.manageSystemACLs is true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -362,7 +362,7 @@ key2: value2' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ --set 'meshGateway.consulServiceName=mesh-gateway' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) @@ -669,13 +669,13 @@ consul services register \ [ "${actual}" = "${exp}" ] } -@test "meshGateway/Deployment: service-init init container with global.bootstrapACLs=true" { +@test "meshGateway/Deployment: service-init init container with acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index badd1a4e68..455f5e4a73 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRole: enabled with global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRole: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRole: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRole: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRole: enabled with client=true and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRole: enabled with client=true and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -50,7 +50,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats index 2f16966253..60f54c8b9a 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: enabled with global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRoleBinding: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: enabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ClusterRoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index 56dbee2411..9899ea3c60 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/Job: enabled with global.bootstrapACLs=true" { +@test "serverACLInitCleanup/Job: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/Job: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/Job: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/Job: enabled with client=true and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/Job: enabled with client=true and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -47,7 +47,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.updatePartition=1' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -58,7 +58,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -c '.spec.template.spec.containers[0].args' | tee /dev/stderr) [ "${actual}" = '["delete-completed-job","-k8s-namespace=default","release-name-consul-server-acl-init"]' ] diff --git a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats index a19bff5146..a1bc249f56 100644 --- a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats @@ -11,22 +11,22 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/PodSecurityPolicy: disabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=false" { +@test "serverACLInitCleanup/PodSecurityPolicy: disabled with global.acls.manageSystemACLs=true and global.enablePodSecurityPolicies=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/PodSecurityPolicy: enabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=true" { +@test "serverACLInitCleanup/PodSecurityPolicy: enabled with global.acls.manageSystemACLs=true and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index 0c1d1d9d93..15190ab0f3 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ServiceAccount: enabled with global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ServiceAccount: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ServiceAccount: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ServiceAccount: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ServiceAccount: enabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInitCleanup/ServiceAccount: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-cleanup-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index f63f60f0f3..646f6dc387 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: enabled with global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRole: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRole: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRole: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: enabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRole: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -50,7 +50,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -r '.rules | map(select(.resources[0] == "serviceaccounts")) | length' | tee /dev/stderr) @@ -64,7 +64,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrole.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index 8ccdc229a8..fa73ff0b3a 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRoleBinding: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRoleBinding: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ClusterRoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index ab7d98c52b..9ace28d79a 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/Job: enabled with global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/Job: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/Job: enabled with client=false global.bootstrapACLs=true" { +@test "serverACLInit/Job: enabled with client=false global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -47,7 +47,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.updatePartition=1' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -58,7 +58,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command[2] | contains("-create-client-token=false")' | tee /dev/stderr) @@ -69,7 +69,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command[2] | contains("-create-client-token=false")' | @@ -84,7 +84,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -94,7 +94,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'dns.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) @@ -105,7 +105,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'dns.enabled=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("allow-dns"))' | tee /dev/stderr) @@ -113,7 +113,7 @@ load _helpers } #-------------------------------------------------------------------- -# aclBindingRuleSelector/global.bootstrapACLs +# aclBindingRuleSelector/global.acls.manageSystemACLs @test "serverACLInit/Job: no acl-binding-rule-selector flag by default" { cd `chart_dir` @@ -130,7 +130,7 @@ load _helpers local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'connectInject.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'connectInject.aclBindingRuleSelector="foo"' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-acl-binding-rule-selector=\"foo\""))' | tee /dev/stderr) @@ -144,7 +144,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | @@ -156,7 +156,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) @@ -167,7 +167,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-enterprise-license-token"))' | tee /dev/stderr) @@ -181,7 +181,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -191,7 +191,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) @@ -202,7 +202,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ @@ -218,7 +218,7 @@ load _helpers cd `chart_dir` local command=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) @@ -238,7 +238,7 @@ load _helpers cd `chart_dir` local ca_cert_volume=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.tls.enabled=true' \ --set 'global.tls.caCert.secretName=foo-ca-cert' \ --set 'global.tls.caCert.secretKey=key' \ @@ -264,7 +264,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) @@ -308,7 +308,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ --set 'syncCatalog.consulNamespaces.mirroringK8SPrefix=k8s-' \ @@ -352,7 +352,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'syncCatalog.enabled=true' \ . | tee /dev/stderr | @@ -395,7 +395,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ @@ -439,7 +439,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'syncCatalog.enabled=true' \ --set 'syncCatalog.consulNamespaces.mirroringK8S=true' \ @@ -487,7 +487,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'connectInject.consulNamespaces.mirroringK8S=true' \ --set 'connectInject.consulNamespaces.mirroringK8SPrefix=k8s-' \ @@ -531,7 +531,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | @@ -574,7 +574,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'connectInject.enabled=true' \ --set 'connectInject.consulNamespaces.mirroringK8S=true' \ @@ -618,7 +618,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enableConsulNamespaces=true' \ --set 'connectInject.enabled=true' \ --set 'connectInject.consulNamespaces.mirroringK8S=true' \ @@ -666,7 +666,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-acl-replication-token"))' | tee /dev/stderr) [ "${actual}" = "false" ] @@ -676,7 +676,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.createReplicationToken=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-acl-replication-token"))' | tee /dev/stderr) @@ -690,7 +690,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr) # Test the flag is not set. @@ -713,7 +713,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretName=name' \ . | tee /dev/stderr) @@ -737,7 +737,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretKey=key' \ . | tee /dev/stderr) @@ -761,7 +761,7 @@ load _helpers cd `chart_dir` local object=$(helm template \ -x templates/server-acl-init-job.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretName=name' \ --set 'global.acls.replicationToken.secretKey=key' \ . | tee /dev/stderr) diff --git a/test/unit/server-acl-init-podsecuritypolicy.bats b/test/unit/server-acl-init-podsecuritypolicy.bats index aee0cb5609..9e52b56aec 100644 --- a/test/unit/server-acl-init-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-podsecuritypolicy.bats @@ -11,22 +11,22 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/PodSecurityPolicy: disabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=false" { +@test "serverACLInit/PodSecurityPolicy: disabled with global.acls.manageSystemACLs=true and global.enablePodSecurityPolicies=false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-podsecuritypolicy.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/PodSecurityPolicy: enabled with global.bootstrapACLs=true and global.enablePodSecurityPolicies=true" { +@test "serverACLInit/PodSecurityPolicy: enabled with global.acls.manageSystemACLs=true and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-podsecuritypolicy.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index 758e0a32a3..6b6e2c1ed8 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -11,32 +11,32 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ServiceAccount: enabled with global.bootstrapACLs=true" { +@test "serverACLInit/ServiceAccount: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/ServiceAccount: disabled with server=false and global.bootstrapACLs=true" { +@test "serverACLInit/ServiceAccount: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/ServiceAccount: enabled with client=false and global.bootstrapACLs=true" { +@test "serverACLInit/ServiceAccount: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-serviceaccount.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index da4a13c2c0..2fed0c3ac1 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -53,13 +53,13 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs -@test "server/ConfigMap: creates acl config with .global.bootstrapACLs enabled" { +@test "server/ConfigMap: creates acl config with .global.acls.manageSystemACLs enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.data["acl-config.json"] | length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -173,7 +173,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -183,7 +183,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretName=name' \ . | tee /dev/stderr | yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) @@ -194,7 +194,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretKey=key' \ . | tee /dev/stderr | yq -r '.data["acl-config.json"]' | yq -r '.acl.enable_token_replication' | tee /dev/stderr) @@ -205,7 +205,7 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-config-configmap.yaml \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.acls.replicationToken.secretName=name' \ --set 'global.acls.replicationToken.secretKey=key' \ . | tee /dev/stderr | diff --git a/test/unit/sync-catalog-clusterrole.bats b/test/unit/sync-catalog-clusterrole.bats index 61932f3641..6f3d538f06 100755 --- a/test/unit/sync-catalog-clusterrole.bats +++ b/test/unit/sync-catalog-clusterrole.bats @@ -67,14 +67,14 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs @test "syncCatalog/ClusterRole: allows secret access with global.bootsrapACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-clusterrole.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules[2].resources[0]' | tee /dev/stderr) [ "${actual}" = "secrets" ] diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 0205619664..1a7b98ecfb 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -341,25 +341,25 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs +# global.acls.manageSystemACLs -@test "syncCatalog/Deployment: CONSUL_HTTP_TOKEN env variable created when global.bootstrapACLs=true" { +@test "syncCatalog/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '[.spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "syncCatalog/Deployment: init container is created when global.bootstrapACLs=true" { +@test "syncCatalog/Deployment: init container is created when global.acls.manageSystemACLs=true" { cd `chart_dir` local object=$(helm template \ -x templates/sync-catalog-deployment.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) @@ -480,7 +480,7 @@ load _helpers local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ --set 'syncCatalog.enabled=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ . | tee /dev/stderr | @@ -668,9 +668,9 @@ load _helpers } #-------------------------------------------------------------------- -# namespaces + global.bootstrapACLs +# namespaces + global.acls.manageSystemACLs -@test "syncCatalog/Deployment: cross namespace policy is not added when global.bootstrapACLs=false" { +@test "syncCatalog/Deployment: cross namespace policy is not added when global.acls.manageSystemACLs=false" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ @@ -681,13 +681,13 @@ load _helpers [ "${actual}" = "false" ] } -@test "syncCatalog/Deployment: cross namespace policy is added when global.bootstrapACLs=true" { +@test "syncCatalog/Deployment: cross namespace policy is added when global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ --set 'syncCatalog.enabled=true' \ --set 'global.enableConsulNamespaces=true' \ - --set 'global.bootstrapACLs=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/values.yaml b/values.yaml index ea39d78146..8a7513fffd 100644 --- a/values.yaml +++ b/values.yaml @@ -38,7 +38,7 @@ global: # Note: support for the catalog sync's liveness and readiness probes was added # to consul-k8s 0.6.0. If using an older consul-k8s version, you may need to # remove these checks to make the sync work. - # If using bootstrapACLs then must be >= 0.10.1. + # If using acls.manageSystemACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. # If using Consul Enterprise namespaces, must be >= 0.12. imageK8S: "hashicorp/consul-k8s:0.12.0" @@ -73,11 +73,6 @@ global: # encryption key. secretKey: "" - # bootstrapACLs will automatically create and assign ACL tokens within - # the Consul cluster. This requires servers to be running inside Kubernetes. - # Additionally requires Consul >= 1.4 and consul-k8s >= 0.10.1. - bootstrapACLs: false - # Enables TLS encryption across the cluster to verify authenticity of the # servers and clients that connect. Note: It is HIGHLY recommended that you also # enable Gossip encryption. @@ -163,8 +158,17 @@ global: # This setting must be true in both primary and secondary datacenters. enabled: false + # [DEPRECATED] Use acls.manageSystemACLs instead. + bootstrapACLs: false + # Configure ACLs. acls: + + # If true, the Helm chart will automatically manage ACL tokens and policies + # for all Consul components. This requires servers to be running inside Kubernetes. + # Additionally requires Consul >= 1.4 and consul-k8s >= 0.10.1. + manageSystemACLs: false + # If true, an ACL token will be created that can be used in secondary # datacenters for replication. This should only be set to true in the # primary datacenter since the replication token must be created from that @@ -766,15 +770,16 @@ connectInject: # Requires Consul >= v1.5 and consul-k8s >= v0.8.0. aclBindingRuleSelector: "serviceaccount.name!=default" - # If not using global.bootstrapACLs and instead manually setting up an auth - # method for Connect inject, set this to the name of your auth method. + # If not using global.acls.manageSystemACLs and instead manually setting up an + # auth method for Connect inject, set this to the name of your auth method. overrideAuthMethodName: "" # aclInjectToken refers to a Kubernetes secret that you have created that contains # an ACL token for your Consul cluster which allows the Connect injector the correct # permissions. This is only needed if Consul namespaces [Enterprise only] and ACLs - # are enabled on the Consul cluster and you are not setting `global.bootstrapACLs` - # to `true`. This token needs to have `operator = "write"` privileges to be able to + # are enabled on the Consul cluster and you are not setting + # `global.acls.manageSystemACLs` to `true`. + # This token needs to have `operator = "write"` privileges to be able to # create Consul namespaces. aclInjectToken: secretName: null @@ -808,7 +813,8 @@ meshGateway: # If mesh gateways are enabled, a Deployment will be created that runs # gateways and Consul Connect will be configured to use gateways. # See https://www.consul.io/docs/connect/mesh_gateway.html - # Requirements: consul >= 1.6.0 and consul-k8s >= 0.9.0 if using global.bootstrapACLs. + # Requirements: consul >= 1.6.0 and consul-k8s >= 0.9.0 if using + # global.acls.manageSystemACLs. enabled: false # Globally configure which mode the gateway should run in. @@ -892,8 +898,8 @@ meshGateway: dnsPolicy: null # Override the default 'mesh-gateway' service name registered in Consul. - # Cannot be used if bootstrapACLs is true since the ACL token generated - # is only for the name 'mesh-gateway'. + # Cannot be used if global.acls.manageSystemACLs is true since the ACL token + # generated is only for the name 'mesh-gateway'. consulServiceName: "" # Port that the gateway will run on inside the container. From c3e16e41ea87fc764f6e3edaf6a21e4d769522f9 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 2 Apr 2020 14:27:02 -0700 Subject: [PATCH 319/739] 0.19.0 Changelog --- CHANGELOG.md | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a8ee83817..7b778759c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,151 @@ ## Unreleased +BREAKING CHANGES: + +* Mesh Gateways: + * `meshGateway.wanAddress` - The following values are no longer supported: + + ```yaml + meshGateway: + wanAddress: + useNodeIP: true + useNodeName: false + host: "" + ``` + + Instead, if previously setting `useNodeIP: true`, now you must set: + ```yaml + meshGateway: + wanAddress: + source: "NodeIP" + ``` + + If previously setting `useNodeName: true`, now you must set: + ```yaml + meshGateway: + wanAddress: + source: "NodeName" + ``` + + If previously setting `host: "example.com"`, now you must set: + ```yaml + meshGateway: + wanAddress: + source: "Static" + static: "example.com" + ``` + where `meshGateway.wanAddress.static` is set to the previous `host` value. + + * `meshGateway.service.enabled` now defaults to `true`. If + previously you were enabling mesh gateways but not enabling the service, + you must now explicitly set this to `false`: + + Previously: + ```yaml + meshGateway: + enabled: true + ``` + + Now: + ```yaml + meshGateway: + enabled: true + service: + enabled: false + ``` + + * `meshGateway.service.type` now defaults to `LoadBalancer` instead of `ClusterIP`. + To set to `ClusterIP` use: + ```yaml + meshGateway: + service: + type: ClusterIP + ``` + + * `meshGateway.containerPort` now defaults to `8443` instead of `443`. This is + to support running in Google Kubernetes Engine by default. This change should + have no effect because the service's targetPort will change accordingly so + you will still be able to route to the mesh gateway as before. + If you wish to keep the port as `443` you must set: + ```yaml + meshGateway: + containerPort: 443 + ``` + +FEATURES: + +* ACLs: Support ACL replication. ACL replication allows two or more Consul clusters + to be federated when ACLs are enabled. One cluster is designated the primary + and the rest are secondaries. The primary cluster replicates its ACLs to + the secondaries. [[GH-368](https://github.com/hashicorp/consul-helm/pull/368)] + + NOTE: This feature requires that the clusters are federated. + + Primary cluster: + + ```yaml + global: + acls: + manageSystemACLs: true + createReplicationToken: true + ``` + + The replication acl token Kubernetes secret is exported from the primary cluster + into the secondaries and then referenced in their Helm config: + + ```yaml + global: + acls: + manageSystemACLs: true + replicationToken: + secretName: name + secretKey: key + ``` + +* Mesh Gateways: Automatically set mesh gateway addresses when using a Kubernetes + Load Balancer service. + To use, set: + + ```yaml + meshGateway: + enabled: true + service: + enabled: true + type: "LoadBalancer" + wanAddress: + source: "Service" + ``` + [[GH-388](https://github.com/hashicorp/consul-helm/pull/388)] + +IMPROVEMENTS: + +* Default to the latest version of consul-k8s: `hashicorp/consul-k8s:0.13.0` +* Default to the latest version of Consul: `consul:1.7.2` +* Allow setting specific secret keys in `server.extraVolumes` [[GH-395](https://github.com/hashicorp/consul-helm/pull/395)] + +BUGFIXES: + +* Mesh Gateways: Mesh gateways are no longer de-registered when their node's Consul + client restarts. [[GH-380](https://github.com/hashicorp/consul-helm/pull/380)] + +DEPRECATIONS: + +* `global.bootstrapACLs` is deprecated. Instead, set `global.acls.manageSystemACLs`. + `global.bootstrapACLs` will be supported for the next three releases. + + Previously: + ```yaml + global: + bootstrapACLs: true + ``` + + Now: + ```yaml + global: + acls: + manageSystemACLs: true + ``` + ## 0.18.0 (Mar 18, 2020) IMPROVEMENTS: From b7f7ed473c7f45f48cec1e455a9a0819b0c3c763 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 3 Apr 2020 09:41:52 -0700 Subject: [PATCH 320/739] Remove global.federation.enabled key Since Consul doesn't have a release that supports federation, remove the ability to turn it on in the helm chart. For users that use a custom binary, they can still set global.federation.enabled=true in their local config and federation will be turned on. --- templates/mesh-gateway-deployment.yaml | 2 ++ templates/server-statefulset.yaml | 2 ++ values.yaml | 9 --------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index afb956baa5..e178c42f1c 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -160,11 +160,13 @@ spec: service { kind = "mesh-gateway" name = "{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}" + {{- if .Values.global.federation }} {{- if .Values.global.federation.enabled }} meta { consul-wan-federation = "1" } {{- end }} + {{- end }} port = {{ .Values.meshGateway.containerPort }} address = "${POD_IP}" tagged_addresses { diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 5d9abac420..3c057bfb97 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -168,9 +168,11 @@ spec: {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ {{- end }} + {{- if .Values.global.federation }} {{- if .Values.global.federation.enabled }} -hcl="connect { enable_mesh_gateway_wan_federation = true }" \ {{- end }} + {{- end }} {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} -hcl="acl { tokens { agent = \"${ACL_REPLICATION_TOKEN}\", replication = \"${ACL_REPLICATION_TOKEN}\" } }" \ {{- end }} diff --git a/values.yaml b/values.yaml index 31296b0131..357565f4fe 100644 --- a/values.yaml +++ b/values.yaml @@ -149,15 +149,6 @@ global: # of both the catalog sync and connect injector. enableConsulNamespaces: false - # Configures Consul datacenter federation. - federation: - # If true, servers and mesh gateways will - # have mesh gateway federation enabled. - # Additional configuration will be needed to provide the addresses of the - # remote datacenter's mesh gateway to federate with. - # This setting must be true in both primary and secondary datacenters. - enabled: false - # [DEPRECATED] Use acls.manageSystemACLs instead. bootstrapACLs: false From e744f49b377f815d50066d4e3231c365fba314f7 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 3 Apr 2020 18:01:43 -0700 Subject: [PATCH 321/739] Run enterprise-license job on upgrades (#407) * Run enterprise-license job on upgrades --- CHANGELOG.md | 2 ++ templates/enterprise-license-job.yaml | 2 +- values.yaml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfab91a79f..4174971fcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ IMPROVEMENTS: enableAutoEncrypt: true ``` +* Run the enterprise license job on Helm upgrades, as well as installs [[GH-407](https://github.com/hashicorp/consul-helm/pull/407)]. + FEATURES: * Add `externalServers` configuration to support configuring the Helm chart with Consul servers diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index ddc6eff67d..1d118c8a0e 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -13,7 +13,7 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} annotations: - "helm.sh/hook": post-install + "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-weight": "100" "helm.sh/hook-delete-policy": hook-succeeded spec: diff --git a/values.yaml b/values.yaml index 1285307e5b..f846f24dfa 100644 --- a/values.yaml +++ b/values.yaml @@ -169,6 +169,7 @@ server: # has been elected. If you are not using an enterprise image # or if you plan to introduce the license key via another route, then set # these fields to null. + # Note: the job to apply license runs on both Helm installs and upgrades. enterpriseLicense: secretName: null secretKey: null From 3d6f040d73d7f5ed4e7cf9e95474d391ec453e83 Mon Sep 17 00:00:00 2001 From: Juned Memon Date: Tue, 31 Mar 2020 17:29:21 +0530 Subject: [PATCH 322/739] Added imagePullSecrets in serviceAccounts --- templates/client-serviceaccount.yaml | 5 +++++ templates/client-snapshot-agent-serviceaccount.yaml | 5 +++++ templates/connect-inject-authmethod-serviceaccount.yaml | 5 +++++ templates/connect-inject-serviceaccount.yaml | 5 +++++ templates/enterprise-license-serviceaccount.yaml | 5 +++++ templates/mesh-gateway-serviceaccount.yaml | 5 +++++ templates/server-acl-init-cleanup-serviceaccount.yaml | 5 +++++ templates/server-acl-init-serviceaccount.yaml | 5 +++++ templates/server-serviceaccount.yaml | 5 +++++ templates/sync-catalog-serviceaccount.yaml | 5 +++++ templates/tls-init-cleanup-serviceaccount.yaml | 5 +++++ templates/tls-init-serviceaccount.yaml | 5 +++++ values.yaml | 1 + 13 files changed, 61 insertions(+) diff --git a/templates/client-serviceaccount.yaml b/templates/client-serviceaccount.yaml index dacdf8f2b7..f62ee81117 100644 --- a/templates/client-serviceaccount.yaml +++ b/templates/client-serviceaccount.yaml @@ -9,4 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} diff --git a/templates/client-snapshot-agent-serviceaccount.yaml b/templates/client-snapshot-agent-serviceaccount.yaml index 8e734019bd..e1a436963c 100644 --- a/templates/client-snapshot-agent-serviceaccount.yaml +++ b/templates/client-snapshot-agent-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/connect-inject-authmethod-serviceaccount.yaml b/templates/connect-inject-authmethod-serviceaccount.yaml index b4a9b2c8ed..064c1957f8 100644 --- a/templates/connect-inject-authmethod-serviceaccount.yaml +++ b/templates/connect-inject-authmethod-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/connect-inject-serviceaccount.yaml b/templates/connect-inject-serviceaccount.yaml index 2bb0919f07..854a2c1e92 100644 --- a/templates/connect-inject-serviceaccount.yaml +++ b/templates/connect-inject-serviceaccount.yaml @@ -9,4 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} diff --git a/templates/enterprise-license-serviceaccount.yaml b/templates/enterprise-license-serviceaccount.yaml index ccb0f37ef9..8d383bd4de 100644 --- a/templates/enterprise-license-serviceaccount.yaml +++ b/templates/enterprise-license-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/mesh-gateway-serviceaccount.yaml b/templates/mesh-gateway-serviceaccount.yaml index 70e8d947ca..0040124387 100644 --- a/templates/mesh-gateway-serviceaccount.yaml +++ b/templates/mesh-gateway-serviceaccount.yaml @@ -10,4 +10,9 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index 82b73865f2..4c79ca0a9d 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index 745ddd55b6..703189362d 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/server-serviceaccount.yaml b/templates/server-serviceaccount.yaml index 0b35ac4e95..f4bfaa4159 100644 --- a/templates/server-serviceaccount.yaml +++ b/templates/server-serviceaccount.yaml @@ -9,4 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} {{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/sync-catalog-serviceaccount.yaml b/templates/sync-catalog-serviceaccount.yaml index 0c4291e5ca..cf8bed1e9d 100644 --- a/templates/sync-catalog-serviceaccount.yaml +++ b/templates/sync-catalog-serviceaccount.yaml @@ -10,4 +10,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} diff --git a/templates/tls-init-cleanup-serviceaccount.yaml b/templates/tls-init-cleanup-serviceaccount.yaml index b62a005b06..56d72229ae 100644 --- a/templates/tls-init-cleanup-serviceaccount.yaml +++ b/templates/tls-init-cleanup-serviceaccount.yaml @@ -10,5 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/tls-init-serviceaccount.yaml b/templates/tls-init-serviceaccount.yaml index e59e44efc4..49f7533109 100644 --- a/templates/tls-init-serviceaccount.yaml +++ b/templates/tls-init-serviceaccount.yaml @@ -13,5 +13,10 @@ metadata: annotations: "helm.sh/hook": pre-install,pre-upgrade "helm.sh/hook-delete-policy": before-hook-creation + {{- if .Values.global.imagePullSecrets }} +secrets: +imagePullSecrets: +- name: {{ .Values.global.imagePullSecrets }} +{{- end }} {{- end }} {{- end }} diff --git a/values.yaml b/values.yaml index 947e514b4a..a02abbb589 100644 --- a/values.yaml +++ b/values.yaml @@ -31,6 +31,7 @@ global: # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" image: "consul:1.7.1" + imagePullSecrets: # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as catalog sync. This can be overridden From 74599abcde03d4ea90a220ae78f51c3608704139 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:05:07 -0700 Subject: [PATCH 323/739] Update values.yaml docs Co-Authored-By: Iryna Shustava --- values.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/values.yaml b/values.yaml index 947e514b4a..1423063ae2 100644 --- a/values.yaml +++ b/values.yaml @@ -156,21 +156,21 @@ global: acls: # If true, the Helm chart will automatically manage ACL tokens and policies - # for all Consul components. This requires servers to be running inside Kubernetes. - # Additionally requires Consul >= 1.4 and consul-k8s >= 0.10.1. + # for all Consul and consul-k8s components. This requires servers to be running inside Kubernetes. + # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.10.1. manageSystemACLs: false # If true, an ACL token will be created that can be used in secondary # datacenters for replication. This should only be set to true in the # primary datacenter since the replication token must be created from that # datacenter. - # In secondary datacenters, the secret will be imported from the primary + # In secondary datacenters, the secret needs to be imported from the primary # datacenter and referenced via global.acls.replicationToken. createReplicationToken: false # replicationToken references a secret containing the replication ACL token. # This token will be used by secondary datacenters to perform ACL replication - # and create ACL tokens and policies + # and create ACL tokens and policies. replicationToken: secretName: null secretKey: null From eb26715a92e82e0933735f65b30f58a61d05a45d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Apr 2020 15:49:12 -0700 Subject: [PATCH 324/739] Use copied consul binary Previously we were testing with a consul-k8s image that has consul in its path but our regular consul-k8s image does not have the consul binary included. Instead, we should use the consul binary that gets copied into the shared volume by the consul-bin init container. init containers run in order and wait until completion until running the next init container so this is safe to do. --- templates/mesh-gateway-deployment.yaml | 8 ++++++-- test/unit/mesh-gateway-deployment.bats | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index e178c42f1c..e39f3c0d4e 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -190,7 +190,7 @@ spec: } EOF - consul services register \ + /consul-bin/consul services register \ {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} -token-file=/consul/service/acl-token \ {{- end }} @@ -198,6 +198,8 @@ spec: volumeMounts: - name: consul-service mountPath: /consul/service + - name: consul-bin + mountPath: /consul-bin {{- if .Values.global.tls.enabled }} {{- if .Values.global.tls.enableAutoEncrypt }} - name: consul-auto-encrypt-ca-cert @@ -303,6 +305,8 @@ spec: - name: consul-service mountPath: /consul/service readOnly: true + - name: consul-bin + mountPath: /consul-bin {{- if .Values.global.tls.enabled }} {{- if .Values.global.tls.enableAutoEncrypt }} - name: consul-auto-encrypt-ca-cert @@ -334,7 +338,7 @@ spec: - consul-k8s - lifecycle-sidecar - -service-config=/consul/service/service.hcl - - -consul-binary=/bin/consul + - -consul-binary=/consul-bin/consul {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - -token-file=/consul/service/acl-token {{- end }} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index d2ccc861d3..76dcab4748 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -663,7 +663,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -718,7 +718,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ -token-file=/consul/service/acl-token \ /consul/service/service.hcl' @@ -772,7 +772,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -820,7 +820,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -866,7 +866,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -912,7 +912,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -973,7 +973,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -1040,7 +1040,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -1089,7 +1089,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -1157,7 +1157,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] @@ -1206,7 +1206,7 @@ service { } EOF -consul services register \ +/consul-bin/consul services register \ /consul/service/service.hcl' [ "${actual}" = "${exp}" ] From 1c033769c9a38055738bd69408a4a04c8ce8ea38 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 7 Apr 2020 12:34:01 -0700 Subject: [PATCH 325/739] Write address.txt to temp file consul-k8s runs as the consul-k8s user who doesn't have permissions to write to / since that's owned by root. Instead, write the address to /tmp where we do have write permissions. --- templates/mesh-gateway-deployment.yaml | 4 ++-- test/unit/mesh-gateway-deployment.bats | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index e39f3c0d4e..ef174007a0 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -136,8 +136,8 @@ spec: consul-k8s service-address \ -k8s-namespace={{ .Release.Namespace }} \ -name={{ template "consul.fullname" . }}-mesh-gateway \ - -output-file=address.txt - WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt + WAN_ADDR="$(cat /tmp/address.txt)" {{- else if eq $source "Static" }} {{- if eq .Values.meshGateway.wanAddress.static "" }}{{ fail "if meshGateway.wanAddress.source=Static then meshGateway.wanAddress.static cannot be empty" }}{{ end }} WAN_ADDR="{{ .Values.meshGateway.wanAddress.static }}" diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 76dcab4748..17d9e359cb 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -632,8 +632,8 @@ key2: value2' \ exp='consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF @@ -687,8 +687,8 @@ EOF consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF @@ -738,8 +738,8 @@ EOF exp='consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF @@ -1009,8 +1009,8 @@ EOF exp='consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF @@ -1126,8 +1126,8 @@ EOF exp='consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF @@ -1175,8 +1175,8 @@ EOF exp='consul-k8s service-address \ -k8s-namespace=default \ -name=release-name-consul-mesh-gateway \ - -output-file=address.txt -WAN_ADDR="$(cat address.txt)" + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" WAN_PORT="443" cat > /consul/service/service.hcl << EOF From 4bea302b90018782782d1a07621f6d88e1bb70a8 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:47:25 -0700 Subject: [PATCH 326/739] Release 0.19.0 --- CHANGELOG.md | 2 ++ Chart.yaml | 2 +- values.yaml | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b21da96503..d7eea59923 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.19.0 (Apr 7, 2020) + BREAKING CHANGES: * Mesh Gateways: diff --git a/Chart.yaml b/Chart.yaml index a7165c2f9f..272070a273 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.18.0 +version: 0.19.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index 1423063ae2..03e12be0c7 100644 --- a/values.yaml +++ b/values.yaml @@ -30,7 +30,7 @@ global: # image: "consul:1.5.0" # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" - image: "consul:1.7.1" + image: "consul:1.7.2" # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as catalog sync. This can be overridden @@ -41,7 +41,7 @@ global: # If using acls.manageSystemACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. # If using Consul Enterprise namespaces, must be >= 0.12. - imageK8S: "hashicorp/consul-k8s:0.12.0" + imageK8S: "hashicorp/consul-k8s:0.13.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running From 5eea9ca01e2523f2a9891dae4c255d13c0d27c9d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 6 Apr 2020 10:10:13 -0700 Subject: [PATCH 327/739] Refactor imagePullSecrets config Allow configuring image pull secrets via service account. To use, set the helm config global: imagePullSecrets: - name: my-secret-with-image-pull-secrets --- CHANGELOG.md | 2 ++ templates/client-serviceaccount.yaml | 7 +++--- .../client-snapshot-agent-serviceaccount.yaml | 7 +++--- ...nect-inject-authmethod-serviceaccount.yaml | 7 +++--- templates/connect-inject-serviceaccount.yaml | 7 +++--- .../enterprise-license-serviceaccount.yaml | 7 +++--- templates/mesh-gateway-serviceaccount.yaml | 7 +++--- ...erver-acl-init-cleanup-serviceaccount.yaml | 7 +++--- templates/server-acl-init-serviceaccount.yaml | 7 +++--- templates/server-serviceaccount.yaml | 9 ++++---- templates/sync-catalog-serviceaccount.yaml | 7 +++--- .../tls-init-cleanup-serviceaccount.yaml | 7 +++--- templates/tls-init-serviceaccount.yaml | 7 +++--- test/unit/client-serviceaccount.bats | 22 +++++++++++++++++- .../client-snapshot-agent-serviceaccount.bats | 21 +++++++++++++++++ ...nect-inject-authmethod-serviceaccount.bats | 23 +++++++++++++++++++ test/unit/connect-inject-serviceaccount.bats | 21 +++++++++++++++++ .../enterprise-license-serviceaccount.bats | 23 +++++++++++++++++++ test/unit/mesh-gateway-serviceaccount.bats | 22 ++++++++++++++++++ ...erver-acl-init-cleanup-serviceaccount.bats | 21 +++++++++++++++++ test/unit/server-acl-init-serviceaccount.bats | 21 +++++++++++++++++ test/unit/server-serviceaccount.bats | 20 ++++++++++++++++ test/unit/sync-catalog-serviceaccount.bats | 21 +++++++++++++++++ .../unit/tls-init-cleanup-serviceaccount.bats | 21 +++++++++++++++++ test/unit/tls-init-serviceaccount.bats | 22 ++++++++++++++++++ values.yaml | 13 ++++++++++- 26 files changed, 320 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b21da96503..59929681b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -130,6 +130,8 @@ FEATURES: ``` [[GH-388](https://github.com/hashicorp/consul-helm/pull/388)] +* Support setting image pull secrets via service accounts [[GH-411](https://github.com/hashicorp/consul-helm/pull/411)]. + IMPROVEMENTS: * Default to the latest version of consul-k8s: `hashicorp/consul-k8s:0.13.0` diff --git a/templates/client-serviceaccount.yaml b/templates/client-serviceaccount.yaml index f62ee81117..08599b9e98 100644 --- a/templates/client-serviceaccount.yaml +++ b/templates/client-serviceaccount.yaml @@ -9,9 +9,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/client-snapshot-agent-serviceaccount.yaml b/templates/client-snapshot-agent-serviceaccount.yaml index e1a436963c..f7c5dc7f50 100644 --- a/templates/client-snapshot-agent-serviceaccount.yaml +++ b/templates/client-snapshot-agent-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/connect-inject-authmethod-serviceaccount.yaml b/templates/connect-inject-authmethod-serviceaccount.yaml index 064c1957f8..0b3330e091 100644 --- a/templates/connect-inject-authmethod-serviceaccount.yaml +++ b/templates/connect-inject-authmethod-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/connect-inject-serviceaccount.yaml b/templates/connect-inject-serviceaccount.yaml index 854a2c1e92..4a26a92f29 100644 --- a/templates/connect-inject-serviceaccount.yaml +++ b/templates/connect-inject-serviceaccount.yaml @@ -9,9 +9,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/enterprise-license-serviceaccount.yaml b/templates/enterprise-license-serviceaccount.yaml index 8d383bd4de..1d0c5e1a37 100644 --- a/templates/enterprise-license-serviceaccount.yaml +++ b/templates/enterprise-license-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/mesh-gateway-serviceaccount.yaml b/templates/mesh-gateway-serviceaccount.yaml index 0040124387..88d39f4358 100644 --- a/templates/mesh-gateway-serviceaccount.yaml +++ b/templates/mesh-gateway-serviceaccount.yaml @@ -10,9 +10,10 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index 4c79ca0a9d..049e75c229 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index 703189362d..d620afb4af 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/server-serviceaccount.yaml b/templates/server-serviceaccount.yaml index f4bfaa4159..bb79b8b223 100644 --- a/templates/server-serviceaccount.yaml +++ b/templates/server-serviceaccount.yaml @@ -9,9 +9,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} {{- end }} -{{- end }} \ No newline at end of file diff --git a/templates/sync-catalog-serviceaccount.yaml b/templates/sync-catalog-serviceaccount.yaml index cf8bed1e9d..67276f9ff1 100644 --- a/templates/sync-catalog-serviceaccount.yaml +++ b/templates/sync-catalog-serviceaccount.yaml @@ -10,9 +10,10 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} diff --git a/templates/tls-init-cleanup-serviceaccount.yaml b/templates/tls-init-cleanup-serviceaccount.yaml index 56d72229ae..64cac71ba6 100644 --- a/templates/tls-init-cleanup-serviceaccount.yaml +++ b/templates/tls-init-cleanup-serviceaccount.yaml @@ -10,10 +10,11 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/templates/tls-init-serviceaccount.yaml b/templates/tls-init-serviceaccount.yaml index 49f7533109..701a2896d6 100644 --- a/templates/tls-init-serviceaccount.yaml +++ b/templates/tls-init-serviceaccount.yaml @@ -13,10 +13,11 @@ metadata: annotations: "helm.sh/hook": pre-install,pre-upgrade "helm.sh/hook-delete-policy": before-hook-creation - {{- if .Values.global.imagePullSecrets }} -secrets: +{{- with .Values.global.imagePullSecrets }} imagePullSecrets: -- name: {{ .Values.global.imagePullSecrets }} +{{- range . }} + - name: {{ .name }} +{{- end }} {{- end }} {{- end }} {{- end }} diff --git a/test/unit/client-serviceaccount.bats b/test/unit/client-serviceaccount.bats index f787e376ea..5ac087e62a 100644 --- a/test/unit/client-serviceaccount.bats +++ b/test/unit/client-serviceaccount.bats @@ -50,4 +50,24 @@ load _helpers . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] -} \ No newline at end of file +} + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "client/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-serviceaccount.yaml \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/client-snapshot-agent-serviceaccount.bats b/test/unit/client-snapshot-agent-serviceaccount.bats index 5e85e328e8..18ecf95c53 100644 --- a/test/unit/client-snapshot-agent-serviceaccount.bats +++ b/test/unit/client-snapshot-agent-serviceaccount.bats @@ -42,3 +42,24 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "client/SnapshotAgentServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/client-snapshot-agent-serviceaccount.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/connect-inject-authmethod-serviceaccount.bats b/test/unit/connect-inject-authmethod-serviceaccount.bats index e84627856f..04f42cce1a 100644 --- a/test/unit/connect-inject-authmethod-serviceaccount.bats +++ b/test/unit/connect-inject-authmethod-serviceaccount.bats @@ -44,3 +44,26 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "connectInjectAuthMethod/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-authmethod-serviceaccount.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + diff --git a/test/unit/connect-inject-serviceaccount.bats b/test/unit/connect-inject-serviceaccount.bats index 8c3944a9e1..c56c206a42 100644 --- a/test/unit/connect-inject-serviceaccount.bats +++ b/test/unit/connect-inject-serviceaccount.bats @@ -53,3 +53,24 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "connectInject/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/connect-inject-serviceaccount.yaml \ + --set 'connectInject.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/enterprise-license-serviceaccount.bats b/test/unit/enterprise-license-serviceaccount.bats index de1970b67c..d28e07e914 100644 --- a/test/unit/enterprise-license-serviceaccount.bats +++ b/test/unit/enterprise-license-serviceaccount.bats @@ -53,3 +53,26 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "enterpriseLicense/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/enterprise-license-serviceaccount.yaml \ + --set 'server.enterpriseLicense.secretName=foo' \ + --set 'server.enterpriseLicense.secretKey=bar' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + diff --git a/test/unit/mesh-gateway-serviceaccount.bats b/test/unit/mesh-gateway-serviceaccount.bats index 5eaf64747a..9684634502 100644 --- a/test/unit/mesh-gateway-serviceaccount.bats +++ b/test/unit/mesh-gateway-serviceaccount.bats @@ -23,3 +23,25 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "meshGateway/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/mesh-gateway-serviceaccount.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index 15190ab0f3..4296cc3362 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -42,3 +42,24 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "serverACLInitCleanup/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index 6b6e2c1ed8..02fa7355cc 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -42,3 +42,24 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "serverACLInit/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/server-serviceaccount.bats b/test/unit/server-serviceaccount.bats index bf1a742803..4e0b5fccdb 100644 --- a/test/unit/server-serviceaccount.bats +++ b/test/unit/server-serviceaccount.bats @@ -51,3 +51,23 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "server/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-serviceaccount.yaml \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/sync-catalog-serviceaccount.bats b/test/unit/sync-catalog-serviceaccount.bats index f4af2306a9..972ad156e4 100755 --- a/test/unit/sync-catalog-serviceaccount.bats +++ b/test/unit/sync-catalog-serviceaccount.bats @@ -51,3 +51,24 @@ load _helpers yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "syncCatalog/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/sync-catalog-serviceaccount.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/tls-init-cleanup-serviceaccount.bats b/test/unit/tls-init-cleanup-serviceaccount.bats index 3d5aef8619..586bf2dbdc 100644 --- a/test/unit/tls-init-cleanup-serviceaccount.bats +++ b/test/unit/tls-init-cleanup-serviceaccount.bats @@ -53,3 +53,24 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "tlsInitCleanup/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/tls-init-cleanup-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/tls-init-serviceaccount.bats b/test/unit/tls-init-serviceaccount.bats index 2ed13a49d3..bf28366728 100644 --- a/test/unit/tls-init-serviceaccount.bats +++ b/test/unit/tls-init-serviceaccount.bats @@ -53,3 +53,25 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "tlsInit/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/tls-init-serviceaccount.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + diff --git a/values.yaml b/values.yaml index a02abbb589..113efe1eda 100644 --- a/values.yaml +++ b/values.yaml @@ -31,7 +31,18 @@ global: # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" image: "consul:1.7.1" - imagePullSecrets: + + # array of objects containing image pull secret names that will be applied to + # each service account. + # This can be used to reference image pull secrets if using + # a custom consul or consul-k8s Docker image. + # See https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry. + # + # Example: + # imagePullSecrets: + # - name: pull-secret-name + # - name: pull-secret-name-2 + imagePullSecrets: [] # imageK8S is the name (and tag) of the consul-k8s Docker image that # is used for functionality such as catalog sync. This can be overridden From 2b29bccf55d14f2a4bbc0a2df6585c64b5302ac7 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 8 Apr 2020 11:28:37 -0700 Subject: [PATCH 328/739] tls-init-cleanup can run if pre-install fails If the pre-install hooks failed, then no non-hook resources get created. This means that the tls-init-cleanup service account doesn't get created. Then if the user runs helm delete, the tls-init-cleanup job tries to run but never starts because it doesn't have its service account. helm delete then hangs forever. The fix is to ensure that the resources needed by the cleanup job get created even if the pre-install hook failed. To do this, we mark them as part of the pre-delete hook and Helm will ensure they get created. Another snag is that Helm creates the Job before the service account. To fix this, we set the weight of the job to 1 so that it is created after the service account. This is a known helm issue: https://github.com/helm/helm/issues/7447 --- templates/tls-init-cleanup-clusterrole.yaml | 3 +++ templates/tls-init-cleanup-clusterrolebinding.yaml | 3 +++ templates/tls-init-cleanup-job.yaml | 2 ++ templates/tls-init-cleanup-podsecuritypolicy.yaml | 3 +++ templates/tls-init-cleanup-serviceaccount.yaml | 3 +++ 5 files changed, 14 insertions(+) diff --git a/templates/tls-init-cleanup-clusterrole.yaml b/templates/tls-init-cleanup-clusterrole.yaml index 02cde16fd1..7458f4e45e 100644 --- a/templates/tls-init-cleanup-clusterrole.yaml +++ b/templates/tls-init-cleanup-clusterrole.yaml @@ -10,6 +10,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded rules: - apiGroups: [""] resources: diff --git a/templates/tls-init-cleanup-clusterrolebinding.yaml b/templates/tls-init-cleanup-clusterrolebinding.yaml index b97efe48d7..c8b14ab24e 100644 --- a/templates/tls-init-cleanup-clusterrolebinding.yaml +++ b/templates/tls-init-cleanup-clusterrolebinding.yaml @@ -10,6 +10,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole diff --git a/templates/tls-init-cleanup-job.yaml b/templates/tls-init-cleanup-job.yaml index 39cc531ef9..cc125c5e6b 100644 --- a/templates/tls-init-cleanup-job.yaml +++ b/templates/tls-init-cleanup-job.yaml @@ -13,6 +13,8 @@ metadata: annotations: "helm.sh/hook": pre-delete "helm.sh/hook-delete-policy": hook-succeeded + {{- /* Hook weight needs to be 1 so that the service account is provisioned first */}} + "helm.sh/hook-weight": "1" spec: template: metadata: diff --git a/templates/tls-init-cleanup-podsecuritypolicy.yaml b/templates/tls-init-cleanup-podsecuritypolicy.yaml index d58e2bd2da..7d32091bec 100644 --- a/templates/tls-init-cleanup-podsecuritypolicy.yaml +++ b/templates/tls-init-cleanup-podsecuritypolicy.yaml @@ -9,6 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded spec: privileged: false # Required to prevent escalations to root. diff --git a/templates/tls-init-cleanup-serviceaccount.yaml b/templates/tls-init-cleanup-serviceaccount.yaml index 64cac71ba6..68c856be3a 100644 --- a/templates/tls-init-cleanup-serviceaccount.yaml +++ b/templates/tls-init-cleanup-serviceaccount.yaml @@ -10,6 +10,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded {{- with .Values.global.imagePullSecrets }} imagePullSecrets: {{- range . }} From 9338c1565b9b3c5ab80fa1c2ecac71c8012ba153 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 8 Apr 2020 12:48:03 -0700 Subject: [PATCH 329/739] Delete tls-init-job on hook creation Without this setting, if the tls init job failed, users wouldn't be able to re-run helm install without manually deleting the job. --- templates/tls-init-job.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index 618035f60c..29c6d8a7cc 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -14,7 +14,7 @@ metadata: annotations: "helm.sh/hook": pre-install,pre-upgrade "helm.sh/hook-weight": "1" - "helm.sh/hook-delete-policy": hook-succeeded + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation spec: template: metadata: From 847106d8a2b170314a7afaedcedfe3f703ade4a4 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 9 Apr 2020 16:54:54 -0700 Subject: [PATCH 330/739] Provide server stateful set DNS names to the ACL init job (#401) * Provide server stateful set DNS names to the ACL init job --- templates/server-acl-init-job.yaml | 9 ++++++--- test/unit/helpers.bats | 2 +- test/unit/server-acl-init-job.bats | 23 +++++++++++++++++++++-- values.yaml | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index bf3d441e34..616615689a 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -80,14 +80,18 @@ spec: - "/bin/sh" - "-ec" - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + consul-k8s server-acl-init \ - -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \ + {{- range $index := until (.Values.server.replicas | int) }} + -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ + {{- end }} -resource-prefix={{ template "consul.fullname" . }} \ -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.global.tls.enabled }} -use-https \ -consul-ca-cert=/consul/tls/ca/tls.crt \ - -consul-tls-server-name=server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }} \ + -server-port=8501 \ {{- end }} {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ @@ -147,7 +151,6 @@ spec: {{- end }} {{- end }} {{- end }} - -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} {{- end }} diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 80e3c3def2..741ad7cb4a 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -101,7 +101,7 @@ load _helpers cd `chart_dir` # Grep for uses of .Release.Name that aren't using it as a label. local actual=$(grep -r '{{ .Release.Name }}' templates/*.yaml | grep -v 'release: ' | tee /dev/stderr ) - [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] + [ "${actual}" = '' ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 9ace28d79a..e63e593fe6 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -77,6 +77,25 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/Job: server address is set to the DNS names of the server stateful set" { + cd `chart_dir` + local command=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # dns @@ -230,8 +249,8 @@ load _helpers actual=$(echo $command | jq -r '. | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "true" ] - actual=$(echo $command | jq -r '. | any(contains("-consul-tls-server-name=server.dc1.consul"))' | tee /dev/stderr) - [ "${actual}" = "true" ] + actual=$(echo $command | jq -r '. | any(contains("-server-port=8501"))' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "serverACLInit/Job: can overwrite CA secret with the provided one" { diff --git a/values.yaml b/values.yaml index d88333dd91..5336a25c0f 100644 --- a/values.yaml +++ b/values.yaml @@ -169,7 +169,7 @@ global: # If true, the Helm chart will automatically manage ACL tokens and policies # for all Consul and consul-k8s components. This requires servers to be running inside Kubernetes. - # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.10.1. + # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.14.0. manageSystemACLs: false # If true, an ACL token will be created that can be used in secondary From 409f95b0c677430d043b4f371862b4f2fb295045 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 13 Apr 2020 14:35:15 -0700 Subject: [PATCH 331/739] Revert "Provide server stateful set DNS names to the ACL init job (#401)" (#424) This reverts commit 847106d8a2b170314a7afaedcedfe3f703ade4a4. --- templates/server-acl-init-job.yaml | 9 +++------ test/unit/helpers.bats | 2 +- test/unit/server-acl-init-job.bats | 23 ++--------------------- values.yaml | 2 +- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 616615689a..bf3d441e34 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -80,18 +80,14 @@ spec: - "/bin/sh" - "-ec" - | - CONSUL_FULLNAME="{{template "consul.fullname" . }}" - consul-k8s server-acl-init \ - {{- range $index := until (.Values.server.replicas | int) }} - -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ - {{- end }} + -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \ -resource-prefix={{ template "consul.fullname" . }} \ -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.global.tls.enabled }} -use-https \ -consul-ca-cert=/consul/tls/ca/tls.crt \ - -server-port=8501 \ + -consul-tls-server-name=server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }} \ {{- end }} {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ @@ -151,6 +147,7 @@ spec: {{- end }} {{- end }} {{- end }} + -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} {{- end }} diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 741ad7cb4a..80e3c3def2 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -101,7 +101,7 @@ load _helpers cd `chart_dir` # Grep for uses of .Release.Name that aren't using it as a label. local actual=$(grep -r '{{ .Release.Name }}' templates/*.yaml | grep -v 'release: ' | tee /dev/stderr ) - [ "${actual}" = '' ] + [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index e63e593fe6..9ace28d79a 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -77,25 +77,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/Job: server address is set to the DNS names of the server stateful set" { - cd `chart_dir` - local command=$(helm template \ - -x templates/server-acl-init-job.yaml \ - --set 'global.acls.manageSystemACLs=true' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) - - local actual - actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - #-------------------------------------------------------------------- # dns @@ -249,8 +230,8 @@ load _helpers actual=$(echo $command | jq -r '. | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "true" ] - actual=$(echo $command | jq -r '. | any(contains("-server-port=8501"))' | tee /dev/stderr) - [ "${actual}" = "true" ] + actual=$(echo $command | jq -r '. | any(contains("-consul-tls-server-name=server.dc1.consul"))' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "serverACLInit/Job: can overwrite CA secret with the provided one" { diff --git a/values.yaml b/values.yaml index 5336a25c0f..d88333dd91 100644 --- a/values.yaml +++ b/values.yaml @@ -169,7 +169,7 @@ global: # If true, the Helm chart will automatically manage ACL tokens and policies # for all Consul and consul-k8s components. This requires servers to be running inside Kubernetes. - # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.14.0. + # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.10.1. manageSystemACLs: false # If true, an ACL token will be created that can be used in secondary From f89be18a9c6e28982424f43338bfeff9df103364 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 16 Apr 2020 10:58:32 -0700 Subject: [PATCH 332/739] Revert "Revert "Provide server stateful set DNS names to the ACL init job (#401)" (#424)" This reverts commit 409f95b0c677430d043b4f371862b4f2fb295045. --- templates/server-acl-init-job.yaml | 9 ++++++--- test/unit/helpers.bats | 2 +- test/unit/server-acl-init-job.bats | 23 +++++++++++++++++++++-- values.yaml | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index bf3d441e34..616615689a 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -80,14 +80,18 @@ spec: - "/bin/sh" - "-ec" - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + consul-k8s server-acl-init \ - -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \ + {{- range $index := until (.Values.server.replicas | int) }} + -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ + {{- end }} -resource-prefix={{ template "consul.fullname" . }} \ -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.global.tls.enabled }} -use-https \ -consul-ca-cert=/consul/tls/ca/tls.crt \ - -consul-tls-server-name=server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }} \ + -server-port=8501 \ {{- end }} {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ @@ -147,7 +151,6 @@ spec: {{- end }} {{- end }} {{- end }} - -expected-replicas={{ .Values.server.replicas }} {{- end }} {{- end }} {{- end }} diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 80e3c3def2..741ad7cb4a 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -101,7 +101,7 @@ load _helpers cd `chart_dir` # Grep for uses of .Release.Name that aren't using it as a label. local actual=$(grep -r '{{ .Release.Name }}' templates/*.yaml | grep -v 'release: ' | tee /dev/stderr ) - [ "${actual}" = 'templates/server-acl-init-job.yaml: -server-label-selector=component=server,app={{ template "consul.name" . }},release={{ .Release.Name }} \' ] + [ "${actual}" = '' ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 9ace28d79a..e63e593fe6 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -77,6 +77,25 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/Job: server address is set to the DNS names of the server stateful set" { + cd `chart_dir` + local command=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + actual=$(echo $command | jq -r '. | any(contains("-server-address=\"${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # dns @@ -230,8 +249,8 @@ load _helpers actual=$(echo $command | jq -r '. | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "true" ] - actual=$(echo $command | jq -r '. | any(contains("-consul-tls-server-name=server.dc1.consul"))' | tee /dev/stderr) - [ "${actual}" = "true" ] + actual=$(echo $command | jq -r '. | any(contains("-server-port=8501"))' | tee /dev/stderr) + [ "${actual}" = "true" ] } @test "serverACLInit/Job: can overwrite CA secret with the provided one" { diff --git a/values.yaml b/values.yaml index d88333dd91..5336a25c0f 100644 --- a/values.yaml +++ b/values.yaml @@ -169,7 +169,7 @@ global: # If true, the Helm chart will automatically manage ACL tokens and policies # for all Consul and consul-k8s components. This requires servers to be running inside Kubernetes. - # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.10.1. + # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.14.0. manageSystemACLs: false # If true, an ACL token will be created that can be used in secondary From 554f93666e929ccc89b3e406c66ee841020e58fb Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Wed, 22 Apr 2020 19:47:04 -0700 Subject: [PATCH 333/739] ACLs: Support external servers (#420) * server-acl-init-job sets server addresses if 'externalServers.enabled' is true * server-acl-init and server-acl-init-cleanup jobs and their related resources now run either when servers are enabled or when externalServers are enabled * Add new acls.bootstrapToken value for providing your own bootstrap token. * Allow custom auth method configuration * Fail if both server and externalServers are enabled --- .../server-acl-init-cleanup-clusterrole.yaml | 4 +- ...r-acl-init-cleanup-clusterrolebinding.yaml | 4 +- templates/server-acl-init-cleanup-job.yaml | 4 +- ...er-acl-init-cleanup-podsecuritypolicy.yaml | 4 +- ...erver-acl-init-cleanup-serviceaccount.yaml | 4 +- templates/server-acl-init-clusterrole.yaml | 11 +- .../server-acl-init-clusterrolebinding.yaml | 4 +- templates/server-acl-init-job.yaml | 48 ++- .../server-acl-init-podsecuritypolicy.yaml | 4 +- templates/server-acl-init-serviceaccount.yaml | 4 +- test/unit/helpers.bats | 6 + .../server-acl-init-cleanup-clusterrole.bats | 32 ++ ...r-acl-init-cleanup-clusterrolebinding.bats | 32 ++ test/unit/server-acl-init-cleanup-job.bats | 32 ++ ...er-acl-init-cleanup-podsecuritypolicy.bats | 35 ++ ...erver-acl-init-cleanup-serviceaccount.bats | 32 ++ test/unit/server-acl-init-clusterrole.bats | 32 ++ .../server-acl-init-clusterrolebinding.bats | 32 ++ test/unit/server-acl-init-job.bats | 323 ++++++++++++++++++ .../server-acl-init-podsecuritypolicy.bats | 35 ++ test/unit/server-acl-init-serviceaccount.bats | 32 ++ values.yaml | 36 +- 22 files changed, 722 insertions(+), 28 deletions(-) diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index 5c03ccc70a..4a9d6277d0 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml index 197d8b85b4..6cdd1b2b59 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index d8f04cd232..45f51479a2 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* See reason for this in server-acl-init-job.yaml */ -}} {{- if eq (int .Values.server.updatePartition) 0 }} diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml index 52dcbd1291..71cedecd43 100644 --- a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index 049e75c229..7094430714 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 kind: ServiceAccount diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index b4a0216971..016e4552a7 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -30,11 +32,8 @@ rules: - apiGroups: [""] resources: - serviceaccounts - verbs: - - get - - apiGroups: [""] - resources: - - services + resourceNames: + - {{ template "consul.fullname" . }}-connect-injector-authmethod-svc-account verbs: - get {{- end }} diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index 1502550204..37ba498e61 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 616615689a..420adfe08f 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* We don't render this job when server.updatePartition > 0 because that means a server rollout is in progress and this job won't complete unless @@ -32,7 +34,7 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init - {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey)) }} + {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey)) }} volumes: {{- if .Values.global.tls.enabled }} - name: consul-ca-cert @@ -46,7 +48,14 @@ spec: - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} - {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} + - name: bootstrap-token + secret: + secretName: {{ .Values.global.acls.bootstrapToken.secretName }} + items: + - key: {{ .Values.global.acls.bootstrapToken.secretKey }} + path: bootstrap-token + {{- else if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} - name: acl-replication-token secret: secretName: {{ .Values.global.acls.replicationToken.secretName }} @@ -63,14 +72,18 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey)) }} + {{- if (or .Values.global.tls.enabled (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey)) }} volumeMounts: {{- if .Values.global.tls.enabled }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} - {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} + - name: bootstrap-token + mountPath: /consul/acl/tokens + readOnly: true + {{- else if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} - name: acl-replication-token mountPath: /consul/acl/tokens readOnly: true @@ -83,16 +96,32 @@ spec: CONSUL_FULLNAME="{{template "consul.fullname" . }}" consul-k8s server-acl-init \ + {{- if .Values.externalServers.enabled }} + {{- if not (or .Values.externalServers.https.address .Values.client.join)}}{{ fail "either client.join or externalServers.https.address must be set if externalServers.enabled is true" }}{{ end -}} + {{- if .Values.externalServers.https.address }} + -server-address={{ .Values.externalServers.https.address }} \ + {{- else }} + {{- range .Values.client.join }} + -server-address={{ . }} \ + {{- end }} + {{- end }} + -server-port={{ .Values.externalServers.https.port }} \ + {{- else }} {{- range $index := until (.Values.server.replicas | int) }} -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ {{- end }} - -resource-prefix={{ template "consul.fullname" . }} \ + {{- end }} + -resource-prefix=${CONSUL_FULLNAME} \ -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.global.tls.enabled }} -use-https \ + {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} -consul-ca-cert=/consul/tls/ca/tls.crt \ + {{- end }} + {{- if not .Values.externalServers.enabled }} -server-port=8501 \ {{- end }} + {{- end }} {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ {{- end }} @@ -101,6 +130,9 @@ spec: {{- end }} {{- if .Values.connectInject.enabled }} -create-inject-auth-method=true \ + {{- if .Values.connectInject.overrideAuthMethodHost }} + -inject-auth-method-host={{ .Values.connectInject.overrideAuthMethodHost }} \ + {{- end }} {{- end }} {{- if .Values.meshGateway.enabled }} -create-mesh-gateway-token=true \ @@ -120,7 +152,9 @@ spec: {{- if .Values.global.acls.createReplicationToken }} -create-acl-replication-token=true \ {{- end }} - {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} + -bootstrap-token-file=/consul/acl/tokens/bootstrap-token \ + {{- else if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} -acl-replication-token-file=/consul/acl/tokens/acl-replication-token \ {{- end }} {{- if .Values.global.enableConsulNamespaces }} diff --git a/templates/server-acl-init-podsecuritypolicy.yaml b/templates/server-acl-init-podsecuritypolicy.yaml index 003e06cbc7..de0884599d 100644 --- a/templates/server-acl-init-podsecuritypolicy.yaml +++ b/templates/server-acl-init-podsecuritypolicy.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index d620afb4af..4e227ab050 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -1,4 +1,6 @@ -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 kind: ServiceAccount diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 741ad7cb4a..a7fee59df6 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -138,6 +138,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'client.join[0]=consul-server.com' \ . | tee /dev/stderr | @@ -162,6 +163,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'externalServers.https.address=consul.io' \ . | tee /dev/stderr | @@ -197,6 +199,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'externalServers.https.address=consul.io' \ --set 'externalServers.https.port=8501' \ @@ -222,6 +225,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'externalServers.https.address=consul.io' \ --set 'externalServers.https.tlsServerName=custom-server-name' \ @@ -237,6 +241,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'externalServers.https.address=consul.io' \ --set 'externalServers.https.useSystemRoots=true' \ @@ -252,6 +257,7 @@ load _helpers -x templates/tests/test-runner.yaml \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'externalServers.https.address=consul.io' \ --set 'externalServers.https.useSystemRoots=true' \ diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index 455f5e4a73..468fbcdeb0 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -43,6 +43,38 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInitCleanup/ClusterRole: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ClusterRole: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInitCleanup/ClusterRole: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-clusterrole.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + #-------------------------------------------------------------------- # global.enablePodSecurityPolicies diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats index 60f54c8b9a..3e3b361e52 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -42,3 +42,35 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "serverACLInitCleanup/ClusterRoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInitCleanup/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index 9899ea3c60..0844aa1604 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -63,3 +63,35 @@ load _helpers yq -c '.spec.template.spec.containers[0].args' | tee /dev/stderr) [ "${actual}" = '["delete-completed-job","-k8s-namespace=default","release-name-consul-server-acl-init"]' ] } + +@test "serverACLInitCleanup/Job: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/Job: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInitCleanup/Job: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-job.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} \ No newline at end of file diff --git a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats index a1bc249f56..026f482e9f 100644 --- a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats @@ -32,3 +32,38 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "serverACLInitCleanup/PodSecurityPolicy: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInitCleanup/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} \ No newline at end of file diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index 4296cc3362..468c4cfb9c 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -43,6 +43,38 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInitCleanup/ServiceAccount: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/ServiceAccount: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInitCleanup/ServiceAccount: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-cleanup-serviceaccount.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + #-------------------------------------------------------------------- # global.imagePullSecrets diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index 646f6dc387..78a352ce2a 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -43,6 +43,38 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/ClusterRole: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRole: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInit/ClusterRole: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-clusterrole.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + #-------------------------------------------------------------------- # connectInject.enabled diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index fa73ff0b3a..df5546f053 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -42,3 +42,35 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "serverACLInit/ClusterRoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInit/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-clusterrolebinding.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} \ No newline at end of file diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index e63e593fe6..03891182ba 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -54,6 +54,38 @@ load _helpers [ "${actual}" = "false" ] } +@test "serverACLInit/Job: enabled with externalServers.enabled=true global.acls.manageSystemACLs=true, but server.enabled set to false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInit/Job: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + @test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { cd `chart_dir` local actual=$(helm template \ @@ -800,3 +832,294 @@ load _helpers yq '.spec.template.spec.containers[0].volumeMounts | map(select(.name == "acl-replication-token")) | length == 1' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# externalServers.enabled + +@test "serverACLInit/Job: fails if external servers are enabled but neither externalServers.https.address nor client.join are set" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "either client.join or externalServers.https.address must be set if externalServers.enabled is true" ]] +} + +@test "serverACLInit/Job: sets server address if externalServers.https.address is set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: sets server address to the client.join value if externalServers.https.address is not set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-address=1.1.1.1"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: prefers externalServers.https.address when both externalServers.https.address and client.join are set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: port 443 is used by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-port=443"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: can override externalServers.https.port" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.https.port=8501' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-port=8501"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: doesn't set server port to 8501 if TLS is enabled and externalServers.enabled is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-port=8501"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: doesn't set the CA cert if TLS is enabled and externalServers.https.useSystemRoots is true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.enabled is true but externalServers.https.useSystemRoots is false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.https.useSystemRoots=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.https.useSystemRoots is true but externalServers.enabled is false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.tls.enabled=true' \ + --set 'externalServers.enabled=false' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.https.useSystemRoots=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.acls.bootstrapToken + +@test "serverACLInit/Job: -bootstrap-token-file is not set by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-bootstrap-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -bootstrap-token-file is not set when acls.bootstrapToken.secretName is set but secretKey is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.bootstrapToken.secretName=name' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-bootstrap-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -bootstrap-token-file is not set when acls.bootstrapToken.secretKey is set but secretName is not" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.bootstrapToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the flag is not set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-bootstrap-token-file"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + # Test the volume doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount doesn't exist + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -bootstrap-token-file is set when acls.bootstrapToken.secretKey and secretName are set" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.bootstrapToken.secretName=name' \ + --set 'global.acls.bootstrapToken.secretKey=key' \ + . | tee /dev/stderr) + + # Test the -bootstrap-token-file flag is set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-bootstrap-token-file=/consul/acl/tokens/bootstrap-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume exists + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | map(select(.name == "bootstrap-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount exists + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | map(select(.name == "bootstrap-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: -bootstrap-token-file is preferred when both acls.bootstrapToken and acls.replicationToken are set" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.bootstrapToken.secretName=name' \ + --set 'global.acls.bootstrapToken.secretKey=key' \ + --set 'global.acls.replicationToken.secretName=replication' \ + --set 'global.acls.replicationToken.secretKey=token' \ + . | tee /dev/stderr) + + # Test the -bootstrap-token-file flag is set. + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].command | any(contains("-bootstrap-token-file=/consul/acl/tokens/bootstrap-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume exists + local actual=$(echo "$object" | + yq '.spec.template.spec.volumes | map(select(.name == "bootstrap-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # Test the volume mount exists + local actual=$(echo "$object" | + yq '.spec.template.spec.containers[0].volumeMounts | map(select(.name == "bootstrap-token")) | length == 1' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# connectInject.overrideAuthMethodHost + +@test "serverACLInit/Job: doesn't set auth method host default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-inject-auth-method-host"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: can provide custom auth method host" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.overrideAuthMethodHost=foo.com' \ + . | tee /dev/stderr| + yq '.spec.template.spec.containers[0].command | any(contains("-inject-auth-method-host=foo.com"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/server-acl-init-podsecuritypolicy.bats b/test/unit/server-acl-init-podsecuritypolicy.bats index 9e52b56aec..61006eef84 100644 --- a/test/unit/server-acl-init-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-podsecuritypolicy.bats @@ -32,3 +32,38 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } + +@test "serverACLInit/PodSecurityPolicy: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + --set 'server.enabled=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInit/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} \ No newline at end of file diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index 02fa7355cc..6c3afc49e0 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -43,6 +43,38 @@ load _helpers [ "${actual}" = "true" ] } +@test "serverACLInit/ServiceAccount: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.https.address=foo.com' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/ServiceAccount: fails if both externalServers.enabled=true and server.enabled=true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'server.enabled=true' \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + +@test "serverACLInit/ServiceAccount: fails if both externalServers.enabled=true and server.enabled not set to false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-serviceaccount.yaml \ + --set 'externalServers.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] +} + #-------------------------------------------------------------------- # global.imagePullSecrets diff --git a/values.yaml b/values.yaml index 5336a25c0f..b6c92fad2e 100644 --- a/values.yaml +++ b/values.yaml @@ -168,21 +168,32 @@ global: acls: # If true, the Helm chart will automatically manage ACL tokens and policies - # for all Consul and consul-k8s components. This requires servers to be running inside Kubernetes. - # Additionally, requires Consul >= 1.4 and consul-k8s >= 0.14.0. + # for all Consul and consul-k8s components. This requires Consul >= 1.4 and consul-k8s >= 0.14.0. manageSystemACLs: false + # bootstrapToken references a Kubernetes secret containing the bootstrap token to use + # for creating policies and tokens for all Consul and consul-k8s components. + # If set, we will skip ACL bootstrapping of the servers and will only initialize + # ACLs for the Consul and consul-k8s system components. + # Requires consul-k8s >= 0.14.0 + bootstrapToken: + secretName: null + secretKey: null + # If true, an ACL token will be created that can be used in secondary # datacenters for replication. This should only be set to true in the # primary datacenter since the replication token must be created from that # datacenter. # In secondary datacenters, the secret needs to be imported from the primary # datacenter and referenced via global.acls.replicationToken. + # Requires consul-k8s >= 0.13.0 createReplicationToken: false # replicationToken references a secret containing the replication ACL token. # This token will be used by secondary datacenters to perform ACL replication # and create ACL tokens and policies. + # This value is ignored if bootstrapToken is also set. + # Requires consul-k8s >= 0.13.0 replicationToken: secretName: null secretKey: null @@ -307,11 +318,14 @@ server: # https_proxy: http://localhost:3128, # no_proxy: internal.domain.com -# Add configuration for Consul servers running externally, -# i.e. outside of Kubernetes. -# This information is required if Consul servers are running -# outside of k8s and you’re setting global.tls.enableAutoEncrypt to true. +# Configuration for Consul servers when the servers are running outside of Kubernetes. +# When running external servers, configuring these values is recommended +# if setting global.tls.enableAutoEncrypt to true (requires consul-k8s >= 0.13.0) +# or global.acls.manageSystemACLs to true (requires consul-k8s >= 0.14.0). externalServers: + # If true, the Helm chart will be configured to talk to the external servers. + # If setting this to true, you must also set server.enabled to false. + # Note that if you are setting client.join property, https.address property is not required. enabled: false # HTTPS configuration for external servers. @@ -319,6 +333,7 @@ externalServers: # not supported. https: # IP, DNS name, or Cloud auto-join string pointing to the external Consul servers. + # Port must be provided separately with the externalServers.https.port property. # Note that if you’re providing the cloud auto-join string and multiple addresses # can be returned, only the first address will be used. # This value is required only if you would like to use @@ -777,10 +792,17 @@ connectInject: # Requires Consul >= v1.5 and consul-k8s >= v0.8.0. aclBindingRuleSelector: "serviceaccount.name!=default" - # If not using global.acls.manageSystemACLs and instead manually setting up an + # If you are not using global.acls.manageSystemACLs and instead manually setting up an # auth method for Connect inject, set this to the name of your auth method. overrideAuthMethodName: "" + # If you are using global.acls.manageSystemACLs but also setting externalServers.enabled + # to true, set overrideAuthMethodHost to the address of the Kubernetes API server. + # This address must to be reachable from the Consul servers. + # Please see https://www.consul.io/docs/acl/auth-methods/kubernetes.html. + # Requires consul-k8s >= 0.14.0. + overrideAuthMethodHost: "" + # aclInjectToken refers to a Kubernetes secret that you have created that contains # an ACL token for your Consul cluster which allows the Connect injector the correct # permissions. This is only needed if Consul namespaces [Enterprise only] and ACLs From 4f6c993f59f91d21351a949829ada6bc57e4c513 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 23 Apr 2020 12:54:09 -0700 Subject: [PATCH 334/739] Reorganize externalServers section (#430) * Consolidate client.join and externalServers.https.address under one value: externalServers.hosts. This value no longer accepts ports, and so if the serf port is non-default, it has to be provided separately. Since it no longer accepts ports, this value was renamed from 'address' to 'hosts'. This was largely based on RFC2396, which defined URL as '@:'. * Deprecate 'client.join'. * Add externalServers.serfLANPort. * Rename externalServers.https.port -> externalServers.httpsPort * Rename externalServers.https.tlsServerName -> externalServers.tlsServerName * Rename externalServers.https.useSystemRoots -> externalServers.useSystemRoots * Rename connectInject.overrideAuthMethodHost -> externalServers.k8sAuthMethodHost --- templates/_helpers.tpl | 16 ++-- templates/client-daemonset.yaml | 7 ++ .../client-snapshot-agent-deployment.yaml | 2 +- templates/connect-inject-deployment.yaml | 2 +- templates/mesh-gateway-deployment.yaml | 2 +- ...er-acl-init-cleanup-podsecuritypolicy.yaml | 2 +- templates/server-acl-init-clusterrole.yaml | 2 +- templates/server-acl-init-job.yaml | 16 ++-- templates/sync-catalog-deployment.yaml | 2 +- templates/tests/test-runner.yaml | 2 +- test/unit/client-daemonset.bats | 57 ++++++++++++++- .../client-snapshot-agent-deployment.bats | 6 +- test/unit/connect-inject-deployment.bats | 6 +- test/unit/helpers.bats | 36 ++++----- test/unit/mesh-gateway-deployment.bats | 6 +- .../server-acl-init-cleanup-clusterrole.bats | 2 +- ...r-acl-init-cleanup-clusterrolebinding.bats | 2 +- test/unit/server-acl-init-cleanup-job.bats | 2 +- ...er-acl-init-cleanup-podsecuritypolicy.bats | 2 +- ...erver-acl-init-cleanup-serviceaccount.bats | 2 +- test/unit/server-acl-init-clusterrole.bats | 2 +- .../server-acl-init-clusterrolebinding.bats | 2 +- test/unit/server-acl-init-job.bats | 73 +++++++++++-------- .../server-acl-init-podsecuritypolicy.bats | 2 +- test/unit/server-acl-init-serviceaccount.bats | 2 +- test/unit/sync-catalog-deployment.bats | 6 +- values.yaml | 65 ++++++++--------- 27 files changed, 201 insertions(+), 125 deletions(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index c0a43bdffe..bbb8e44aff 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -76,17 +76,17 @@ This template is for an init container. consul-k8s get-consul-client-ca \ -output-file=/consul/tls/client/ca/tls.crt \ {{- if .Values.externalServers.enabled }} - {{- if not (or .Values.externalServers.https.address .Values.client.join)}}{{ fail "either client.join or externalServers.https.address must be set if externalServers.enabled is true" }}{{ end -}} - {{- if .Values.externalServers.https.address }} - -server-addr={{ .Values.externalServers.https.address }} \ + {{- if not (or .Values.externalServers.hosts .Values.client.join)}}{{ fail "either client.join or externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} + {{- if .Values.externalServers.hosts }} + -server-addr={{ quote (first .Values.externalServers.hosts) }} \ {{- else }} -server-addr={{ quote (first .Values.client.join) }} \ {{- end }} - -server-port={{ .Values.externalServers.https.port }} \ - {{- if .Values.externalServers.https.tlsServerName }} - -tls-server-name={{ .Values.externalServers.https.tlsServerName }} \ + -server-port={{ .Values.externalServers.httpsPort }} \ + {{- if .Values.externalServers.tlsServerName }} + -tls-server-name={{ .Values.externalServers.tlsServerName }} \ {{- end }} - {{- if not .Values.externalServers.https.useSystemRoots }} + {{- if not .Values.externalServers.useSystemRoots }} -ca-file=/consul/tls/ca/tls.crt {{- end }} {{- else }} @@ -95,7 +95,7 @@ This template is for an init container. -ca-file=/consul/tls/ca/tls.crt {{- end }} volumeMounts: - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert mountPath: /consul/tls/ca {{- end }} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 619c8c8944..676f3f0d2a 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -205,11 +205,18 @@ spec: {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} -encrypt="${GOSSIP_KEY}" \ {{- end }} + {{- if or .Values.client.join (and .Values.externalServers.enabled .Values.externalServers.hosts) }} {{- if .Values.client.join }} {{- range $value := .Values.client.join }} -retry-join={{ quote $value }} \ {{- end }} {{- else }} + {{- $serfPort := (.Values.externalServers.serfLANPort | int) -}} + {{- range $host := .Values.externalServers.hosts }} + -retry-join={{ printf "%s:%d" $host $serfPort | quote}} \ + {{- end }} + {{- end }} + {{- else }} {{- if .Values.server.enabled }} {{- range $index := until (.Values.server.replicas | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index 9f01f8dab3..a09a3a8605 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -52,7 +52,7 @@ spec: emptyDir: {} {{- end }} {{- if .Values.global.tls.enabled }} - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 420f950a14..0f4227232e 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -169,7 +169,7 @@ spec: secretName: {{ .Values.connectInject.certs.secretName }} {{- end }} {{- if .Values.global.tls.enabled }} - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index ef174007a0..da9ca9e4d6 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -53,7 +53,7 @@ spec: emptyDir: medium: "Memory" {{- if .Values.global.tls.enabled }} - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml index 71cedecd43..f5bd06936e 100644 --- a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 016e4552a7..74668ca634 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -46,4 +46,4 @@ rules: - use {{- end }} {{- end }} -{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 420adfe08f..0bdc9b7411 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -97,15 +97,17 @@ spec: consul-k8s server-acl-init \ {{- if .Values.externalServers.enabled }} - {{- if not (or .Values.externalServers.https.address .Values.client.join)}}{{ fail "either client.join or externalServers.https.address must be set if externalServers.enabled is true" }}{{ end -}} - {{- if .Values.externalServers.https.address }} - -server-address={{ .Values.externalServers.https.address }} \ + {{- if not (or .Values.externalServers.hosts .Values.client.join)}}{{ fail "either client.join or externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} + {{- if .Values.externalServers.hosts }} + {{- range .Values.externalServers.hosts }} + -server-address={{ . }} \ + {{- end }} {{- else }} {{- range .Values.client.join }} -server-address={{ . }} \ {{- end }} {{- end }} - -server-port={{ .Values.externalServers.https.port }} \ + -server-port={{ .Values.externalServers.httpsPort }} \ {{- else }} {{- range $index := until (.Values.server.replicas | int) }} -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ @@ -115,7 +117,7 @@ spec: -k8s-namespace={{ .Release.Namespace }} \ {{- if .Values.global.tls.enabled }} -use-https \ - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} -consul-ca-cert=/consul/tls/ca/tls.crt \ {{- end }} {{- if not .Values.externalServers.enabled }} @@ -130,8 +132,8 @@ spec: {{- end }} {{- if .Values.connectInject.enabled }} -create-inject-auth-method=true \ - {{- if .Values.connectInject.overrideAuthMethodHost }} - -inject-auth-method-host={{ .Values.connectInject.overrideAuthMethodHost }} \ + {{- if and .Values.externalServers.enabled .Values.externalServers.k8sAuthMethodHost }} + -inject-auth-method-host={{ .Values.externalServers.k8sAuthMethodHost }} \ {{- end }} {{- end }} {{- if .Values.meshGateway.enabled }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index ff00f30e34..6b35d66ed6 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -31,7 +31,7 @@ spec: serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog {{- if .Values.global.tls.enabled }} volumes: - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index cb2a5897ed..bc836606b1 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -14,7 +14,7 @@ metadata: spec: {{- if .Values.global.tls.enabled }} volumes: - {{- if not (and .Values.externalServers.enabled .Values.externalServers.https.useSystemRoots) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - name: consul-ca-cert secret: {{- if .Values.global.tls.caCert.secretName }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index d17ee62383..dc9f917bf6 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -75,7 +75,7 @@ load _helpers #-------------------------------------------------------------------- # retry-join -@test "client/DaemonSet: retry join gets populated" { +@test "client/DaemonSet: retry join gets populated by default" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ @@ -86,6 +86,61 @@ load _helpers [ "${actual}" = "true" ] } +@test "client/DaemonSet: retry join gets populated when client.join is set" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=1.1.1.1' \ + --set 'client.join[1]=2.2.2.2' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: retry join gets populated when externalServers.hosts is set" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.hosts[1]=2.2.2.2' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1:8301\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2:8301\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: can set non-default serf LAN port for external servers" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.hosts[1]=2.2.2.2' \ + --set 'externalServers.serfLANPort=5555' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1:5555\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2:5555\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # grpc diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index 4f71df03ad..730205e41c 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -322,15 +322,15 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { +@test "client/SnapshotAgentDeployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { cd `chart_dir` local actual=$(helm template \ -x templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'global.tls.enabled=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 9a14e0781d..8112707d67 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -486,7 +486,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "connectInject/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { +@test "connectInject/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { cd `chart_dir` local actual=$(helm template \ -x templates/connect-inject-deployment.yaml \ @@ -494,8 +494,8 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index a7fee59df6..3af163f50d 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -132,7 +132,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "helper/consul.getAutoEncryptClientCA: uses client.join string if externalServers.enabled is true but the address is not provided" { +@test "helper/consul.getAutoEncryptClientCA: uses client.join string if externalServers.enabled is true but the hosts are not provided" { cd `chart_dir` local command=$(helm template \ -x templates/tests/test-runner.yaml \ @@ -149,7 +149,7 @@ load _helpers [ "${actual}" = "true" ] # check the default server port is 443 if not provided - actual=$(echo $command | jq ' . | contains("-server-port=443")') + actual=$(echo $command | jq ' . | contains("-server-port=8501")') [ "${actual}" = "true" ] # check server's CA cert @@ -157,7 +157,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "helper/consul.getAutoEncryptClientCA: can set the provided server address if externalServers.enabled is true" { +@test "helper/consul.getAutoEncryptClientCA: can set the provided server hosts if externalServers.enabled is true" { cd `chart_dir` local command=$(helm template \ -x templates/tests/test-runner.yaml \ @@ -165,16 +165,16 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=consul.io' \ + --set 'externalServers.hosts[0]=consul.io' \ . | tee /dev/stderr | yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) # check server address - actual=$(echo $command | jq ' . | contains("-server-addr=consul.io")') + actual=$(echo $command | jq ' . | contains("-server-addr=\"consul.io\"")') [ "${actual}" = "true" ] # check the default server port is 443 if not provided - actual=$(echo $command | jq ' . | contains("-server-port=443")') + actual=$(echo $command | jq ' . | contains("-server-port=8501")') [ "${actual}" = "true" ] # check server's CA cert @@ -182,7 +182,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "helper/consul.getAutoEncryptClientCA: fails if externalServers.enabled is true but neither client.join nor externalServers.https.address are provided" { +@test "helper/consul.getAutoEncryptClientCA: fails if externalServers.enabled is true but neither client.join nor externalServers.hosts[0] are provided" { cd `chart_dir` run helm template \ -x templates/tests/test-runner.yaml \ @@ -190,7 +190,7 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'externalServers.enabled=true' . [ "$status" -eq 1 ] - [[ "$output" =~ "either client.join or externalServers.https.address must be set if externalServers.enabled is true" ]] + [[ "$output" =~ "either client.join or externalServers.hosts must be set if externalServers.enabled is true" ]] } @test "helper/consul.getAutoEncryptClientCA: can set the provided port if externalServers.enabled is true" { @@ -201,17 +201,17 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=consul.io' \ - --set 'externalServers.https.port=8501' \ + --set 'externalServers.hosts[0]=consul.io' \ + --set 'externalServers.httpsPort=443' \ . | tee /dev/stderr | yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) # check server address - actual=$(echo $command | jq ' . | contains("-server-addr=consul.io")') + actual=$(echo $command | jq ' . | contains("-server-addr=\"consul.io\"")') [ "${actual}" = "true" ] # check the default server port is 443 if not provided - actual=$(echo $command | jq ' . | contains("-server-port=8501")') + actual=$(echo $command | jq ' . | contains("-server-port=443")') [ "${actual}" = "true" ] # check server's CA cert @@ -227,8 +227,8 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=consul.io' \ - --set 'externalServers.https.tlsServerName=custom-server-name' \ + --set 'externalServers.hosts[0]=consul.io' \ + --set 'externalServers.tlsServerName=custom-server-name' \ . | tee /dev/stderr | yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ") | contains("-tls-server-name=custom-server-name")' | tee /dev/stderr) @@ -243,8 +243,8 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=consul.io' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=consul.io' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ") | contains("-ca-file=/consul/tls/ca/tls.crt")' | tee /dev/stderr) @@ -259,8 +259,8 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=consul.io' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=consul.io' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").volumeMounts[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 17d9e359cb..38389a9f71 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -601,7 +601,7 @@ key2: value2' \ [ "${actual}" = "true" ] } -@test "meshGateway/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { +@test "meshGateway/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -610,8 +610,8 @@ key2: value2' \ --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index 468fbcdeb0..8807b59292 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -50,7 +50,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats index 3e3b361e52..4ffbdbe9c5 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -50,7 +50,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index 0844aa1604..f7442b2ea5 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -71,7 +71,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats index 026f482e9f..49793a26e8 100644 --- a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats @@ -41,7 +41,7 @@ load _helpers --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index 468c4cfb9c..157b6d0f0c 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -50,7 +50,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index 78a352ce2a..5349d21499 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -50,7 +50,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index df5546f053..4c9b428ff3 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -50,7 +50,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 03891182ba..b3c90427c5 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -61,7 +61,7 @@ load _helpers --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -836,7 +836,7 @@ load _helpers #-------------------------------------------------------------------- # externalServers.enabled -@test "serverACLInit/Job: fails if external servers are enabled but neither externalServers.https.address nor client.join are set" { +@test "serverACLInit/Job: fails if external servers are enabled but neither externalServers.hosts nor client.join are set" { cd `chart_dir` run helm template \ -x templates/server-acl-init-job.yaml \ @@ -844,23 +844,23 @@ load _helpers --set 'server.enabled=false' \ --set 'externalServers.enabled=true' . [ "$status" -eq 1 ] - [[ "$output" =~ "either client.join or externalServers.https.address must be set if externalServers.enabled is true" ]] + [[ "$output" =~ "either client.join or externalServers.hosts must be set if externalServers.enabled is true" ]] } -@test "serverACLInit/Job: sets server address if externalServers.https.address is set" { +@test "serverACLInit/Job: sets server address if externalServers.hosts are set" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: sets server address to the client.join value if externalServers.https.address is not set" { +@test "serverACLInit/Job: sets server address to the client.join value if externalServers.hosts are not set" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -873,7 +873,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/Job: prefers externalServers.https.address when both externalServers.https.address and client.join are set" { +@test "serverACLInit/Job: prefers externalServers.hosts when both externalServers.hosts and client.join are set" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -881,40 +881,40 @@ load _helpers --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: port 443 is used by default" { +@test "serverACLInit/Job: port 8501 is used by default" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-server-port=443"))' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].command | any(contains("-server-port=8501"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: can override externalServers.https.port" { +@test "serverACLInit/Job: can override externalServers.httpsPort" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.https.port=8501' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.httpsPort=443' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-server-port=8501"))' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].command | any(contains("-server-port=443"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: doesn't set server port to 8501 if TLS is enabled and externalServers.enabled is true" { +@test "serverACLInit/Job: uses only the port from externalServers.httpsPort if TLS is enabled and externalServers.enabled is false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -922,13 +922,14 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.httpsPort=443' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-server-port=8501"))' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/Job: doesn't set the CA cert if TLS is enabled and externalServers.https.useSystemRoots is true" { +@test "serverACLInit/Job: doesn't set the CA cert if TLS is enabled and externalServers.useSystemRoots is true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -936,14 +937,14 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.enabled is true but externalServers.https.useSystemRoots is false" { +@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.enabled is true but externalServers.useSystemRoots is false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ @@ -951,22 +952,22 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.https.useSystemRoots=false' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.useSystemRoots=false' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.https.useSystemRoots is true but externalServers.enabled is false" { +@test "serverACLInit/Job: sets the CA cert if TLS is enabled and externalServers.useSystemRoots is true but externalServers.enabled is false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'global.tls.enabled=true' \ --set 'externalServers.enabled=false' \ - --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=1.1.1.1' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-consul-ca-cert=/consul/tls/ca/tls.crt"))' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -1098,14 +1099,23 @@ load _helpers [ "${actual}" = "true" ] } -#-------------------------------------------------------------------- -# connectInject.overrideAuthMethodHost +@test "serverACLInit/Job: doesn't set auth method host by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-inject-auth-method-host"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} -@test "serverACLInit/Job: doesn't set auth method host default" { +@test "serverACLInit/Job: doesn't set auth method host by default when externalServers.k8sAuthMethodHost is provided but externalServers.enabled is false" { cd `chart_dir` local actual=$(helm template \ -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ + --set 'externalServers.k8sAuthMethodHost=foo.com' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-inject-auth-method-host"))' | tee /dev/stderr) @@ -1118,7 +1128,10 @@ load _helpers -x templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'connectInject.enabled=true' \ - --set 'connectInject.overrideAuthMethodHost=foo.com' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.k8sAuthMethodHost=foo.com' \ . | tee /dev/stderr| yq '.spec.template.spec.containers[0].command | any(contains("-inject-auth-method-host=foo.com"))' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-podsecuritypolicy.bats b/test/unit/server-acl-init-podsecuritypolicy.bats index 61006eef84..60d43247c2 100644 --- a/test/unit/server-acl-init-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-podsecuritypolicy.bats @@ -41,7 +41,7 @@ load _helpers --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index 6c3afc49e0..433e7131cf 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -50,7 +50,7 @@ load _helpers --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ + --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 1a7b98ecfb..79d05fc6ba 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -488,7 +488,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "syncCatalog/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.https.useSystemRoots=true" { +@test "syncCatalog/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { cd `chart_dir` local actual=$(helm template \ -x templates/sync-catalog-deployment.yaml \ @@ -496,8 +496,8 @@ load _helpers --set 'global.tls.enabled=true' \ --set 'global.tls.enableAutoEncrypt=true' \ --set 'externalServers.enabled=true' \ - --set 'externalServers.https.address=foo.com' \ - --set 'externalServers.https.useSystemRoots=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ . | tee /dev/stderr | yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] diff --git a/values.yaml b/values.yaml index b6c92fad2e..b4ef0959af 100644 --- a/values.yaml +++ b/values.yaml @@ -325,36 +325,40 @@ server: externalServers: # If true, the Helm chart will be configured to talk to the external servers. # If setting this to true, you must also set server.enabled to false. - # Note that if you are setting client.join property, https.address property is not required. enabled: false - # HTTPS configuration for external servers. - # Note: HTTP connections to the servers are - # not supported. - https: - # IP, DNS name, or Cloud auto-join string pointing to the external Consul servers. - # Port must be provided separately with the externalServers.https.port property. - # Note that if you’re providing the cloud auto-join string and multiple addresses - # can be returned, only the first address will be used. - # This value is required only if you would like to use - # a different server address from the one specified - # in the client.join property. - address: null - - # The HTTPS port of the server. - port: 443 + # An array of external Consul server hosts that clients will use to join with servers + # as well as for HTTP/HTTPS connections from the components in this Helm chart. + # Valid values include IPs, DNS names, or Cloud auto-join string. + # Ports must be provided separately below. + hosts: [] + + # The Serf LAN port that the clients will use to join the server cluster. + serfLANPort: 8301 - # tlsServerName is the server name to use as the SNI - # host header when connecting with HTTPS. - # This property is useful in case ‘externalServers.https.address’ - # is not or can not be included in the server certificate’s SANs. - tlsServerName: null + # The HTTPS port of the Consul servers. + httpsPort: 8501 - # If true, the Helm chart will ignore the CA set in - # global.tls.caCert and will rely on the container's - # system CAs for TLS verification when talking to Consul servers. - # Otherwise, the chart will use global.tls.caCert. - useSystemRoots: false + # tlsServerName is the server name to use as the SNI + # host header when connecting with HTTPS. + tlsServerName: null + + # If true, the Helm chart will ignore the CA set in + # global.tls.caCert and will rely on the container's + # system CAs for TLS verification when talking to Consul servers. + # Otherwise, the chart will use global.tls.caCert. + useSystemRoots: false + + # If you are setting global.acls.manageSystemACLs and connectInject.enabled to true, + # set k8sAuthMethodHost to the address of the Kubernetes API server. + # This address must to be reachable from the Consul servers. + # Please see https://www.consul.io/docs/acl/auth-methods/kubernetes.html. + # Requires consul-k8s >= 0.14.0. + # + # You could retrieve this value from your kubeconfig by running: + # kubectl config view \ + # -o jsonpath="{.clusters[?(@.name=='')].cluster.server}" + k8sAuthMethodHost: null # Client, when enabled, configures Consul clients to run on every node # within the Kube cluster. The current deployment model follows a traditional @@ -362,6 +366,8 @@ externalServers: client: enabled: "-" image: null + + # [DEPRECATED] Please use externalServers.hosts and externalServers.serfLANPort. join: null # dataDirectoryHostPath is an absolute path to a directory on the host machine @@ -796,13 +802,6 @@ connectInject: # auth method for Connect inject, set this to the name of your auth method. overrideAuthMethodName: "" - # If you are using global.acls.manageSystemACLs but also setting externalServers.enabled - # to true, set overrideAuthMethodHost to the address of the Kubernetes API server. - # This address must to be reachable from the Consul servers. - # Please see https://www.consul.io/docs/acl/auth-methods/kubernetes.html. - # Requires consul-k8s >= 0.14.0. - overrideAuthMethodHost: "" - # aclInjectToken refers to a Kubernetes secret that you have created that contains # an ACL token for your Consul cluster which allows the Connect injector the correct # permissions. This is only needed if Consul namespaces [Enterprise only] and ACLs From 2bf9d15f0544adb1564a451cf090abad5e8fd22d Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 23 Apr 2020 22:53:47 -0700 Subject: [PATCH 335/739] Add a script to generate Helm config for HCS servers --- scripts/generate-helm-config-for-hcs.sh | 110 ++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100755 scripts/generate-helm-config-for-hcs.sh diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh new file mode 100755 index 0000000000..7ce2342e4d --- /dev/null +++ b/scripts/generate-helm-config-for-hcs.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +############################################################################ +# WARNING: This script is experimental and is not meant for production use # +############################################################################ +# +# Script to retrieve configuration from Hashicorp Consul Service on Azure, +# bootstrap ACLs, and create Kubernetes secrets and Helm config file +# to install this Helm chart. + +set -e + +: "${subscription_id?subscription_id environment variable required}" +: "${resource_group?resource_group environment variable required}" +: "${managed_app_name?managed_app_name environment variable required}" +: "${cluster_name?cluster_name environment variable required}" + +echo "-> Fetching cluster configuration from Azure" +cluster_resource=$(az resource show --ids "/subscriptions/${subscription_id}/resourceGroups/${resource_group}/providers/Microsoft.Solutions/applications/${managed_app_name}/customconsulClusters/${cluster_name}" --api-version 2018-09-01-preview) +cluster_config_file_base64=$(echo "${cluster_resource}" | jq -r .properties.consulConfigFile) +ca_file_base64=$(echo "${cluster_resource}" | jq -r .properties.consulCaFile) + +echo "Writing cluster configuration to consul.json" +echo "${cluster_config_file_base64}" | base64 --decode | jq . > consul.json + +echo "Writing CA certificate chain to ca.pem" +echo "${ca_file_base64}" | base64 --decode > ca.pem +echo + +echo "-> Bootstrapping ACLs" + +# Extract the URL for the servers. +# First, check if the external endpoint is enabled and if yes, use the external endpoint URL. +# Otherwise, use the private endpoint URL. +external_endpoint_enabled=$(echo "${cluster_resource}" | jq -r .properties.consulExternalEndpoint) +if [ "$external_endpoint_enabled" == "enabled" ]; then + server_url=$(echo "${cluster_resource}" | jq -r .properties.consulExternalEndpointUrl) +else + server_url=$(echo "${cluster_resource}" | jq -r .properties.consulPrivateEndpointUrl) +fi + +# Call Consul bootstrap API and save the bootstrap secret +# to a Kubernetes secret if successful. +output=$(curl -sX PUT "${server_url}"/v1/acl/bootstrap) +if grep -i "permission denied" <<< "$output"; then + echo "ACL system already bootstrapped." + echo "Please update 'global.acls.bootstrapToken' values in the generated Helm config to point to the Kubernetes secret containing the bootstrap token." +elif grep -i "ACL support disabled" <<< "$output"; then + echo "ACLs not enabled on this cluster." + exit 1 +else + echo "Successfully bootstrapped ACLs" + echo "Creating Kubernetes secret for the bootstrap token ${managed_app_name}-bootstrap-token" + kubectl create secret generic "${managed_app_name}"-bootstrap-token \ + --from-literal="token=$(echo "${output}" | jq -r .SecretID)" +fi + +echo +echo "-> Creating Kubernetes secret ${managed_app_name}-consul-ca-cert" +kubectl create secret generic "${managed_app_name}"-consul-ca-cert --from-file='tls.crt=./ca.pem' + +echo +echo "-> Creating Kubernetes secret ${managed_app_name}-gossip-key" +gossip_key=$(jq -r .encrypt consul.json) +kubectl create secret generic "${managed_app_name}"-gossip-key --from-literal=key="${gossip_key}" + +retry_join=$(jq -r --compact-output .retry_join consul.json) +kube_api_server=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$(kubectl config current-context)\")].cluster.server}") +consul_version=$(echo "${cluster_resource}" | jq -r .properties.consulInitialVersion | cut -d'v' -f2) + +echo +echo "-> Writing Helm config to config.yaml" +cat > config.yaml << EOF +global: + enabled: false + image: hashicorp/consul-enterprise:${consul_version}-ent + datacenter: $(jq -r .datacenter consul.json) + acls: + manageSystemACLs: true + bootstrapToken: + secretName: ${managed_app_name}-bootstrap-token + secretKey: token + gossipEncryption: + secretName: ${managed_app_name}-gossip-key + secretKey: key + tls: + enabled: true + enableAutoEncrypt: true + caCert: + secretName: ${managed_app_name}-consul-ca-cert + secretKey: tls.crt +externalServers: + enabled: true + hosts: ${retry_join} + httpsPort: 443 + useSystemRoots: true + k8sAuthMethodHost: ${kube_api_server} +client: + enabled: true + # If you are using Kubenet in your AKS cluster, + # uncomment the line below. + # exposeGossipPorts: true +connectInject: + enabled: true +syncCatalog: + enabled: true +EOF + +echo +echo "Done" \ No newline at end of file From 0782222495be5f328e8e4a2e7a00f5250fbfc5c9 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 23 Apr 2020 22:54:09 -0700 Subject: [PATCH 336/739] Bump consul-k8s version --- values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/values.yaml b/values.yaml index b4ef0959af..269b0e1e6e 100644 --- a/values.yaml +++ b/values.yaml @@ -53,7 +53,7 @@ global: # If using acls.manageSystemACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. # If using Consul Enterprise namespaces, must be >= 0.12. - imageK8S: "hashicorp/consul-k8s:0.13.0" + imageK8S: "hashicorp/consul-k8s:0.14.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running From 7af1fac2f36143ab3e9e74dbee1a2daeaadf508b Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 23 Apr 2020 23:45:09 -0700 Subject: [PATCH 337/739] Update Changelog --- CHANGELOG.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d57e5b45..627e7a973d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,75 @@ ## Unreleased +BREAKING CHANGES: + +* External Servers [[GH-430](https://github.com/hashicorp/consul-helm/pull/430)]: + * `externalServers.https.address` moved to `externalServers.hosts` + and changed its type from `string` to `array`. + * `externalServers.https.port` moved to `externalServers.httpsPort` + and its default value changed from `443` to `8501`. + * `externalServers.https.tlsServerName` moved to `externalServers.tlsServerName`. + * `externalServers.https.useSystemRoots` moved to `externalServers.useSystemRoots`. + + For example, if previously setting `externalServers` like so: + + ```yaml + externalServers: + https: + address: example.com + port: 443 + tlsServerName: null + useSystemRoots: false + ``` + + Now you need to change it to the following: + + ```yaml + externalServers: + hosts: [example.com] + httpsPort: 443 + tlsServerName: null + useSystemRoots: false + ``` + +FEATURES: + +* Support managing ACLs when running Consul servers externally to Kubernetes: + + * ACLs: Support providing your own bootstrap token [[GH-420](https://github.com/hashicorp/consul-helm/pull/420)]. + If provided, the `server-acl-init` job will skip server ACL bootstrapping. + + Example: + + ```yaml + global: + acls: + manageSystemACLs: true + bootstrapToken: + secretName: bootstrap-token + secretKey: token + ``` + + * External Servers: Add `externalServers.k8sAuthMethodHost` to allow configuring a custom location + of the Kubernetes API server for the auth method created in Consul [[GH-420](https://github.com/hashicorp/consul-helm/pull/420)]. + The Kubernetes API server provided here must be reachable from the external Consul servers. + + Example: + + ```yaml + externalServers: + enabled: true + k8sAuthMethodHost: https://kubernetes-api.example.com:443 + ``` + +IMPROVEMENTS: + +* Default to the latest version of consul-k8s: hashicorp/consul-k8s:0.14.0 + +DEPRECATIONS: + +* `client.join` has been deprecated. Please use `externalServers.hosts` and `externalServers.serfLANPort` instead. + `client.join` will be supported for the next three releases. + ## 0.19.0 (Apr 7, 2020) BREAKING CHANGES: From 9aa98eb12b3ddafd912a469dfd72ccca768a4797 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 24 Apr 2020 10:04:10 -0700 Subject: [PATCH 338/739] Update scripts/generate-helm-config-for-hcs.sh Co-Authored-By: Luke Kysow <1034429+lkysow@users.noreply.github.com> --- CHANGELOG.md | 4 +-- scripts/generate-helm-config-for-hcs.sh | 28 ++++++++++------- templates/client-daemonset.yaml | 10 +++++-- test/unit/client-daemonset.bats | 40 +++++++++++++++++++++---- values.yaml | 2 +- 5 files changed, 62 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 627e7a973d..96954d175c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ BREAKING CHANGES: ```yaml externalServers: https: - address: example.com + address: "example.com" port: 443 tlsServerName: null useSystemRoots: false @@ -25,7 +25,7 @@ BREAKING CHANGES: ```yaml externalServers: - hosts: [example.com] + hosts: ["example.com"] httpsPort: 443 tlsServerName: null useSystemRoots: false diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh index 7ce2342e4d..4405601b2a 100755 --- a/scripts/generate-helm-config-for-hcs.sh +++ b/scripts/generate-helm-config-for-hcs.sh @@ -8,14 +8,19 @@ # bootstrap ACLs, and create Kubernetes secrets and Helm config file # to install this Helm chart. -set -e +set -euo pipefail : "${subscription_id?subscription_id environment variable required}" : "${resource_group?resource_group environment variable required}" : "${managed_app_name?managed_app_name environment variable required}" : "${cluster_name?cluster_name environment variable required}" -echo "-> Fetching cluster configuration from Azure" +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[0;93m' +NOCOLOR='\033[0m' + +echo -e "${YELLOW}-> Fetching cluster configuration from Azure${NOCOLOR}" cluster_resource=$(az resource show --ids "/subscriptions/${subscription_id}/resourceGroups/${resource_group}/providers/Microsoft.Solutions/applications/${managed_app_name}/customconsulClusters/${cluster_name}" --api-version 2018-09-01-preview) cluster_config_file_base64=$(echo "${cluster_resource}" | jq -r .properties.consulConfigFile) ca_file_base64=$(echo "${cluster_resource}" | jq -r .properties.consulCaFile) @@ -27,7 +32,7 @@ echo "Writing CA certificate chain to ca.pem" echo "${ca_file_base64}" | base64 --decode > ca.pem echo -echo "-> Bootstrapping ACLs" +echo -e "${YELLOW}-> Bootstrapping ACLs${NOCOLOR}" # Extract the URL for the servers. # First, check if the external endpoint is enabled and if yes, use the external endpoint URL. @@ -41,12 +46,12 @@ fi # Call Consul bootstrap API and save the bootstrap secret # to a Kubernetes secret if successful. -output=$(curl -sX PUT "${server_url}"/v1/acl/bootstrap) +output=$(curl --connect-timeout 30 -sSX PUT "${server_url}"/v1/acl/bootstrap) if grep -i "permission denied" <<< "$output"; then echo "ACL system already bootstrapped." - echo "Please update 'global.acls.bootstrapToken' values in the generated Helm config to point to the Kubernetes secret containing the bootstrap token." + echo -e "${RED}Please update 'global.acls.bootstrapToken' values in the generated Helm config to point to the Kubernetes secret containing the bootstrap token.${NOCOLOR}" elif grep -i "ACL support disabled" <<< "$output"; then - echo "ACLs not enabled on this cluster." + echo -e "${RED}ACLs not enabled on this cluster.${NOCOLOR}" exit 1 else echo "Successfully bootstrapped ACLs" @@ -56,11 +61,11 @@ else fi echo -echo "-> Creating Kubernetes secret ${managed_app_name}-consul-ca-cert" +echo -e "${YELLOW}-> Creating Kubernetes secret ${managed_app_name}-consul-ca-cert${NOCOLOR}" kubectl create secret generic "${managed_app_name}"-consul-ca-cert --from-file='tls.crt=./ca.pem' echo -echo "-> Creating Kubernetes secret ${managed_app_name}-gossip-key" +echo -e "${YELLOW}-> Creating Kubernetes secret ${managed_app_name}-gossip-key${NOCOLOR}" gossip_key=$(jq -r .encrypt consul.json) kubectl create secret generic "${managed_app_name}"-gossip-key --from-literal=key="${gossip_key}" @@ -69,10 +74,11 @@ kube_api_server=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$(ku consul_version=$(echo "${cluster_resource}" | jq -r .properties.consulInitialVersion | cut -d'v' -f2) echo -echo "-> Writing Helm config to config.yaml" +echo -e "${YELLOW}-> Writing Helm config to config.yaml${NOCOLOR}" cat > config.yaml << EOF global: enabled: false + name: consul image: hashicorp/consul-enterprise:${consul_version}-ent datacenter: $(jq -r .datacenter consul.json) acls: @@ -97,7 +103,7 @@ externalServers: k8sAuthMethodHost: ${kube_api_server} client: enabled: true - # If you are using Kubenet in your AKS cluster, + # If you are using Kubenet in your AKS cluster (the default network), # uncomment the line below. # exposeGossipPorts: true connectInject: @@ -107,4 +113,4 @@ syncCatalog: EOF echo -echo "Done" \ No newline at end of file +echo -e "${GREEN}Done${GREEN}" diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 676f3f0d2a..74a17eb960 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -208,12 +208,18 @@ spec: {{- if or .Values.client.join (and .Values.externalServers.enabled .Values.externalServers.hosts) }} {{- if .Values.client.join }} {{- range $value := .Values.client.join }} - -retry-join={{ quote $value }} \ + -retry-join={{ $value }} \ {{- end }} {{- else }} + {{- if .Values.externalServers.serfLANPort }} {{- $serfPort := (.Values.externalServers.serfLANPort | int) -}} {{- range $host := .Values.externalServers.hosts }} - -retry-join={{ printf "%s:%d" $host $serfPort | quote}} \ + -retry-join={{ printf "%s:%d" $host $serfPort }} \ + {{- end }} + {{- else }} + {{- range $host := .Values.externalServers.hosts }} + -retry-join={{ $host }} \ + {{- end }} {{- end }} {{- end }} {{- else }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index dc9f917bf6..63b75c1dcd 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -97,10 +97,10 @@ load _helpers . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].command') - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1"))' | tee /dev/stderr) [ "${actual}" = "true" ] - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2"))' | tee /dev/stderr) [ "${actual}" = "true" ] } @@ -115,10 +115,38 @@ load _helpers . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].command') - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1:8301\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1"))' | tee /dev/stderr) [ "${actual}" = "true" ] - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2:8301\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: retry join can be set to a cloud-auto join string" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]="provider=my-cloud config=val"' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"provider=my-cloud config=val\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: retry join can be set to a go-sockaddr" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]="{{ GetPrivateIP }}""' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"{{ GetPrivateIP }}\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } @@ -134,10 +162,10 @@ load _helpers . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].command') - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1:5555\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1:5555"))' | tee /dev/stderr) [ "${actual}" = "true" ] - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2:5555\""))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2:5555"))' | tee /dev/stderr) [ "${actual}" = "true" ] } diff --git a/values.yaml b/values.yaml index 269b0e1e6e..ed9beab96b 100644 --- a/values.yaml +++ b/values.yaml @@ -334,7 +334,7 @@ externalServers: hosts: [] # The Serf LAN port that the clients will use to join the server cluster. - serfLANPort: 8301 + serfLANPort: null # The HTTPS port of the Consul servers. httpsPort: 8501 From 142b4e69cfc2d06e323ca1e482eb84eea6d15474 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 24 Apr 2020 15:25:02 -0700 Subject: [PATCH 339/739] Don't re-use client.join as an HTTP hosts of the external servers --- CHANGELOG.md | 36 ++++++++-- scripts/generate-helm-config-for-hcs.sh | 31 ++++++--- templates/_helpers.tpl | 6 +- templates/client-daemonset.yaml | 13 ---- .../server-acl-init-cleanup-clusterrole.yaml | 1 - ...r-acl-init-cleanup-clusterrolebinding.yaml | 1 - templates/server-acl-init-cleanup-job.yaml | 1 - ...er-acl-init-cleanup-podsecuritypolicy.yaml | 1 - ...erver-acl-init-cleanup-serviceaccount.yaml | 1 - templates/server-acl-init-clusterrole.yaml | 1 - .../server-acl-init-clusterrolebinding.yaml | 1 - templates/server-acl-init-job.yaml | 8 +-- .../server-acl-init-podsecuritypolicy.yaml | 1 - templates/server-acl-init-serviceaccount.yaml | 1 - test/unit/client-daemonset.bats | 65 ------------------- test/unit/helpers.bats | 29 +-------- .../server-acl-init-cleanup-clusterrole.bats | 19 ------ ...r-acl-init-cleanup-clusterrolebinding.bats | 19 ------ test/unit/server-acl-init-cleanup-job.bats | 19 ------ ...er-acl-init-cleanup-podsecuritypolicy.bats | 21 ------ ...erver-acl-init-cleanup-serviceaccount.bats | 19 ------ test/unit/server-acl-init-clusterrole.bats | 19 ------ .../server-acl-init-clusterrolebinding.bats | 19 ------ test/unit/server-acl-init-job.bats | 31 +-------- .../server-acl-init-podsecuritypolicy.bats | 21 ------ test/unit/server-acl-init-serviceaccount.bats | 19 ------ values.yaml | 15 ++--- 27 files changed, 65 insertions(+), 353 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96954d175c..2e2b79811d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ BREAKING CHANGES: ```yaml externalServers: + enabled: true https: address: "example.com" port: 443 @@ -25,12 +26,42 @@ BREAKING CHANGES: ```yaml externalServers: + enabled: true hosts: ["example.com"] httpsPort: 443 tlsServerName: null useSystemRoots: false ``` +* Auto-encrypt: You can no longer re-use `client.join` property if using auto-encrypt + with `externalServers.enabled` set to `true`. You must provide Consul server HTTPS address + via `externalServers.hosts` and `externalServers.httpsPort`. + + For example, if previously setting: + + ```yaml + tls: + enabled: true + enabledAutoEncrypt: true + externalServers: + enabled: true + client: + join: ["consul.example.com"] + ``` + + Now you need to change it to: + + ```yaml + tls: + enabled: true + enabledAutoEncrypt: true + externalServers: + enabled: true + hosts: ["consul.example.com"] + client: + join: ["consul.example.com"] + ``` + FEATURES: * Support managing ACLs when running Consul servers externally to Kubernetes: @@ -65,11 +96,6 @@ IMPROVEMENTS: * Default to the latest version of consul-k8s: hashicorp/consul-k8s:0.14.0 -DEPRECATIONS: - -* `client.join` has been deprecated. Please use `externalServers.hosts` and `externalServers.serfLANPort` instead. - `client.join` will be supported for the next three releases. - ## 0.19.0 (Apr 7, 2020) BREAKING CHANGES: diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh index 4405601b2a..f600479e52 100755 --- a/scripts/generate-helm-config-for-hcs.sh +++ b/scripts/generate-helm-config-for-hcs.sh @@ -44,30 +44,40 @@ else server_url=$(echo "${cluster_resource}" | jq -r .properties.consulPrivateEndpointUrl) fi +# Use managed_app_name as a resource prefix for Kubernetes resources +# We need to convert it to lower case because of Kubernetes resource restrictions. +# https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ +kube_resource_prefix=$(echo "${managed_app_name}" | tr '[:upper:]' '[:lower:]') + # Call Consul bootstrap API and save the bootstrap secret # to a Kubernetes secret if successful. output=$(curl --connect-timeout 30 -sSX PUT "${server_url}"/v1/acl/bootstrap) if grep -i "permission denied" <<< "$output"; then echo "ACL system already bootstrapped." echo -e "${RED}Please update 'global.acls.bootstrapToken' values in the generated Helm config to point to the Kubernetes secret containing the bootstrap token.${NOCOLOR}" + echo -e "${RED}You can create a secret like so:${NOCOLOR}" + echo -e "${RED}kubectl create secret generic ${kube_resource_prefix}-bootstrap-token \${NOCOLOR}" + echo -e "${RED} --from-literal="token="${NOCOLOR}" elif grep -i "ACL support disabled" <<< "$output"; then echo -e "${RED}ACLs not enabled on this cluster.${NOCOLOR}" exit 1 else - echo "Successfully bootstrapped ACLs" - echo "Creating Kubernetes secret for the bootstrap token ${managed_app_name}-bootstrap-token" - kubectl create secret generic "${managed_app_name}"-bootstrap-token \ + echo "Successfully bootstrapped ACLs. Writing ACL bootstrap output to acls.json" + echo "$output" > acls.json + + echo "Creating Kubernetes secret for the bootstrap token ${kube_resource_prefix}-bootstrap-token" + kubectl create secret generic "${kube_resource_prefix}"-bootstrap-token \ --from-literal="token=$(echo "${output}" | jq -r .SecretID)" fi echo -echo -e "${YELLOW}-> Creating Kubernetes secret ${managed_app_name}-consul-ca-cert${NOCOLOR}" -kubectl create secret generic "${managed_app_name}"-consul-ca-cert --from-file='tls.crt=./ca.pem' +echo -e "${YELLOW}-> Creating Kubernetes secret ${kube_resource_prefix}-consul-ca-cert${NOCOLOR}" +kubectl create secret generic "${kube_resource_prefix}"-consul-ca-cert --from-file='tls.crt=./ca.pem' echo -echo -e "${YELLOW}-> Creating Kubernetes secret ${managed_app_name}-gossip-key${NOCOLOR}" +echo -e "${YELLOW}-> Creating Kubernetes secret ${kube_resource_prefix}-gossip-key${NOCOLOR}" gossip_key=$(jq -r .encrypt consul.json) -kubectl create secret generic "${managed_app_name}"-gossip-key --from-literal=key="${gossip_key}" +kubectl create secret generic "${kube_resource_prefix}"-gossip-key --from-literal=key="${gossip_key}" retry_join=$(jq -r --compact-output .retry_join consul.json) kube_api_server=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$(kubectl config current-context)\")].cluster.server}") @@ -84,16 +94,16 @@ global: acls: manageSystemACLs: true bootstrapToken: - secretName: ${managed_app_name}-bootstrap-token + secretName: ${kube_resource_prefix}-bootstrap-token secretKey: token gossipEncryption: - secretName: ${managed_app_name}-gossip-key + secretName: ${kube_resource_prefix}-gossip-key secretKey: key tls: enabled: true enableAutoEncrypt: true caCert: - secretName: ${managed_app_name}-consul-ca-cert + secretName: ${kube_resource_prefix}-consul-ca-cert secretKey: tls.crt externalServers: enabled: true @@ -106,6 +116,7 @@ client: # If you are using Kubenet in your AKS cluster (the default network), # uncomment the line below. # exposeGossipPorts: true + join: ${retry_join} connectInject: enabled: true syncCatalog: diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index bbb8e44aff..984098f28c 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -76,12 +76,8 @@ This template is for an init container. consul-k8s get-consul-client-ca \ -output-file=/consul/tls/client/ca/tls.crt \ {{- if .Values.externalServers.enabled }} - {{- if not (or .Values.externalServers.hosts .Values.client.join)}}{{ fail "either client.join or externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} - {{- if .Values.externalServers.hosts }} + {{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} -server-addr={{ quote (first .Values.externalServers.hosts) }} \ - {{- else }} - -server-addr={{ quote (first .Values.client.join) }} \ - {{- end }} -server-port={{ .Values.externalServers.httpsPort }} \ {{- if .Values.externalServers.tlsServerName }} -tls-server-name={{ .Values.externalServers.tlsServerName }} \ diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 74a17eb960..c8748f305e 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -205,24 +205,11 @@ spec: {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} -encrypt="${GOSSIP_KEY}" \ {{- end }} - {{- if or .Values.client.join (and .Values.externalServers.enabled .Values.externalServers.hosts) }} {{- if .Values.client.join }} {{- range $value := .Values.client.join }} -retry-join={{ $value }} \ {{- end }} {{- else }} - {{- if .Values.externalServers.serfLANPort }} - {{- $serfPort := (.Values.externalServers.serfLANPort | int) -}} - {{- range $host := .Values.externalServers.hosts }} - -retry-join={{ printf "%s:%d" $host $serfPort }} \ - {{- end }} - {{- else }} - {{- range $host := .Values.externalServers.hosts }} - -retry-join={{ $host }} \ - {{- end }} - {{- end }} - {{- end }} - {{- else }} {{- if .Values.server.enabled }} {{- range $index := until (.Values.server.replicas | int) }} -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index 4a9d6277d0..e11ca88abd 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml index 6cdd1b2b59..24f0809da2 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index 45f51479a2..87f9b45311 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* See reason for this in server-acl-init-job.yaml */ -}} diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml index f5bd06936e..0f5ac1a0e7 100644 --- a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index 7094430714..db81edfe3f 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 74668ca634..84cd91d794 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index 37ba498e61..ff079b6016 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 0bdc9b7411..7849b96c2c 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -97,16 +97,10 @@ spec: consul-k8s server-acl-init \ {{- if .Values.externalServers.enabled }} - {{- if not (or .Values.externalServers.hosts .Values.client.join)}}{{ fail "either client.join or externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} - {{- if .Values.externalServers.hosts }} + {{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} {{- range .Values.externalServers.hosts }} -server-address={{ . }} \ {{- end }} - {{- else }} - {{- range .Values.client.join }} - -server-address={{ . }} \ - {{- end }} - {{- end }} -server-port={{ .Values.externalServers.httpsPort }} \ {{- else }} {{- range $index := until (.Values.server.replicas | int) }} diff --git a/templates/server-acl-init-podsecuritypolicy.yaml b/templates/server-acl-init-podsecuritypolicy.yaml index de0884599d..1a45be2919 100644 --- a/templates/server-acl-init-podsecuritypolicy.yaml +++ b/templates/server-acl-init-podsecuritypolicy.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- if .Values.global.enablePodSecurityPolicies }} diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index 4e227ab050..3b429ff4cd 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -1,5 +1,4 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} -{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} apiVersion: v1 diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 63b75c1dcd..e4a3e84d1d 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -104,71 +104,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/DaemonSet: retry join gets populated when externalServers.hosts is set" { - cd `chart_dir` - local command=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'externalServers.hosts[0]=1.1.1.1' \ - --set 'externalServers.hosts[1]=2.2.2.2' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command') - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1"))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "client/DaemonSet: retry join can be set to a cloud-auto join string" { - cd `chart_dir` - local command=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'externalServers.hosts[0]="provider=my-cloud config=val"' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command') - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"provider=my-cloud config=val\""))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "client/DaemonSet: retry join can be set to a go-sockaddr" { - cd `chart_dir` - local command=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'externalServers.hosts[0]="{{ GetPrivateIP }}""' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command') - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"{{ GetPrivateIP }}\""))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "client/DaemonSet: can set non-default serf LAN port for external servers" { - cd `chart_dir` - local command=$(helm template \ - -x templates/client-daemonset.yaml \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'externalServers.hosts[0]=1.1.1.1' \ - --set 'externalServers.hosts[1]=2.2.2.2' \ - --set 'externalServers.serfLANPort=5555' \ - . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command') - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1:5555"))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2:5555"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - #-------------------------------------------------------------------- # grpc diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 3af163f50d..cff0dea249 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -132,31 +132,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "helper/consul.getAutoEncryptClientCA: uses client.join string if externalServers.enabled is true but the hosts are not provided" { - cd `chart_dir` - local command=$(helm template \ - -x templates/tests/test-runner.yaml \ - --set 'global.tls.enabled=true' \ - --set 'global.tls.enableAutoEncrypt=true' \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'client.join[0]=consul-server.com' \ - . | tee /dev/stderr | - yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | join(" ")' | tee /dev/stderr) - - # check server address - actual=$(echo $command | jq ' . | contains("-server-addr=\"consul-server.com\"")') - [ "${actual}" = "true" ] - - # check the default server port is 443 if not provided - actual=$(echo $command | jq ' . | contains("-server-port=8501")') - [ "${actual}" = "true" ] - - # check server's CA cert - actual=$(echo $command | jq ' . | contains("-ca-file=/consul/tls/ca/tls.crt")') - [ "${actual}" = "true" ] -} - @test "helper/consul.getAutoEncryptClientCA: can set the provided server hosts if externalServers.enabled is true" { cd `chart_dir` local command=$(helm template \ @@ -182,7 +157,7 @@ load _helpers [ "${actual}" = "true" ] } -@test "helper/consul.getAutoEncryptClientCA: fails if externalServers.enabled is true but neither client.join nor externalServers.hosts[0] are provided" { +@test "helper/consul.getAutoEncryptClientCA: fails if externalServers.enabled is true but externalServers.hosts are not provided" { cd `chart_dir` run helm template \ -x templates/tests/test-runner.yaml \ @@ -190,7 +165,7 @@ load _helpers --set 'global.tls.enableAutoEncrypt=true' \ --set 'externalServers.enabled=true' . [ "$status" -eq 1 ] - [[ "$output" =~ "either client.join or externalServers.hosts must be set if externalServers.enabled is true" ]] + [[ "$output" =~ "externalServers.hosts must be set if externalServers.enabled is true" ]] } @test "helper/consul.getAutoEncryptClientCA: can set the provided port if externalServers.enabled is true" { diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-clusterrole.bats index 8807b59292..7b82bae808 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-clusterrole.bats @@ -56,25 +56,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRole: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInitCleanup/ClusterRole: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - #-------------------------------------------------------------------- # global.enablePodSecurityPolicies diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats index 4ffbdbe9c5..ff4821ea26 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-clusterrolebinding.bats @@ -55,22 +55,3 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "serverACLInitCleanup/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInitCleanup/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} diff --git a/test/unit/server-acl-init-cleanup-job.bats b/test/unit/server-acl-init-cleanup-job.bats index f7442b2ea5..d00194d079 100644 --- a/test/unit/server-acl-init-cleanup-job.bats +++ b/test/unit/server-acl-init-cleanup-job.bats @@ -76,22 +76,3 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "serverACLInitCleanup/Job: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-job.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInitCleanup/Job: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-job.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} \ No newline at end of file diff --git a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats index 49793a26e8..87c56a3e3a 100644 --- a/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-cleanup-podsecuritypolicy.bats @@ -46,24 +46,3 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "serverACLInitCleanup/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ - --set 'global.enablePodSecurityPolicies=true' \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInitCleanup/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-podsecuritypolicy.yaml \ - --set 'global.enablePodSecurityPolicies=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} \ No newline at end of file diff --git a/test/unit/server-acl-init-cleanup-serviceaccount.bats b/test/unit/server-acl-init-cleanup-serviceaccount.bats index 157b6d0f0c..96cdf5b754 100644 --- a/test/unit/server-acl-init-cleanup-serviceaccount.bats +++ b/test/unit/server-acl-init-cleanup-serviceaccount.bats @@ -56,25 +56,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ServiceAccount: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-serviceaccount.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInitCleanup/ServiceAccount: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-cleanup-serviceaccount.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - #-------------------------------------------------------------------- # global.imagePullSecrets diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-clusterrole.bats index 5349d21499..01bf3f0197 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-clusterrole.bats @@ -56,25 +56,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRole: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-clusterrole.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInit/ClusterRole: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-clusterrole.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - #-------------------------------------------------------------------- # connectInject.enabled diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-clusterrolebinding.bats index 4c9b428ff3..fe833ef2b8 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-clusterrolebinding.bats @@ -55,22 +55,3 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "serverACLInit/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInit/ClusterRoleBinding: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} \ No newline at end of file diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index b3c90427c5..2296bf7e31 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -836,7 +836,7 @@ load _helpers #-------------------------------------------------------------------- # externalServers.enabled -@test "serverACLInit/Job: fails if external servers are enabled but neither externalServers.hosts nor client.join are set" { +@test "serverACLInit/Job: fails if external servers are enabled but externalServers.hosts are not set" { cd `chart_dir` run helm template \ -x templates/server-acl-init-job.yaml \ @@ -844,7 +844,7 @@ load _helpers --set 'server.enabled=false' \ --set 'externalServers.enabled=true' . [ "$status" -eq 1 ] - [[ "$output" =~ "either client.join or externalServers.hosts must be set if externalServers.enabled is true" ]] + [[ "$output" =~ "externalServers.hosts must be set if externalServers.enabled is true" ]] } @test "serverACLInit/Job: sets server address if externalServers.hosts are set" { @@ -860,33 +860,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/Job: sets server address to the client.join value if externalServers.hosts are not set" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-acl-init-job.yaml \ - --set 'global.acls.manageSystemACLs=true' \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-server-address=1.1.1.1"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - -@test "serverACLInit/Job: prefers externalServers.hosts when both externalServers.hosts and client.join are set" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/server-acl-init-job.yaml \ - --set 'global.acls.manageSystemACLs=true' \ - --set 'server.enabled=false' \ - --set 'externalServers.enabled=true' \ - --set 'client.join[0]=1.1.1.1' \ - --set 'externalServers.hosts[0]=foo.com' \ - . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - @test "serverACLInit/Job: port 8501 is used by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-acl-init-podsecuritypolicy.bats b/test/unit/server-acl-init-podsecuritypolicy.bats index 60d43247c2..bc92744547 100644 --- a/test/unit/server-acl-init-podsecuritypolicy.bats +++ b/test/unit/server-acl-init-podsecuritypolicy.bats @@ -46,24 +46,3 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } - -@test "serverACLInit/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-podsecuritypolicy.yaml \ - --set 'global.enablePodSecurityPolicies=true' \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInit/PodSecurityPolicy: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-podsecuritypolicy.yaml \ - --set 'global.enablePodSecurityPolicies=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} \ No newline at end of file diff --git a/test/unit/server-acl-init-serviceaccount.bats b/test/unit/server-acl-init-serviceaccount.bats index 433e7131cf..07927fe186 100644 --- a/test/unit/server-acl-init-serviceaccount.bats +++ b/test/unit/server-acl-init-serviceaccount.bats @@ -56,25 +56,6 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/ServiceAccount: fails if both externalServers.enabled=true and server.enabled=true" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-serviceaccount.yaml \ - --set 'server.enabled=true' \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - -@test "serverACLInit/ServiceAccount: fails if both externalServers.enabled=true and server.enabled not set to false" { - cd `chart_dir` - run helm template \ - -x templates/server-acl-init-serviceaccount.yaml \ - --set 'externalServers.enabled=true' . - [ "$status" -eq 1 ] - [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] -} - #-------------------------------------------------------------------- # global.imagePullSecrets diff --git a/values.yaml b/values.yaml index ed9beab96b..50fb602c44 100644 --- a/values.yaml +++ b/values.yaml @@ -327,15 +327,16 @@ externalServers: # If setting this to true, you must also set server.enabled to false. enabled: false - # An array of external Consul server hosts that clients will use to join with servers - # as well as for HTTP/HTTPS connections from the components in this Helm chart. + # An array of external Consul server hosts that are used to make + # HTTPS connections from the components in this Helm chart. # Valid values include IPs, DNS names, or Cloud auto-join string. - # Ports must be provided separately below. + # The port must be provided separately below. + # NOTE: client.join must also be set to the hosts that should be + # used to join the cluster. In most cases the client.join values + # should be the same, however they may be different if you + # wish to use separate hosts for the HTTPS connections. hosts: [] - # The Serf LAN port that the clients will use to join the server cluster. - serfLANPort: null - # The HTTPS port of the Consul servers. httpsPort: 8501 @@ -366,8 +367,6 @@ externalServers: client: enabled: "-" image: null - - # [DEPRECATED] Please use externalServers.hosts and externalServers.serfLANPort. join: null # dataDirectoryHostPath is an absolute path to a directory on the host machine From 495b5793dd580f188e72fb3193e97cfc38e469a7 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 24 Apr 2020 16:20:59 -0700 Subject: [PATCH 340/739] Release 0.20.0 --- CHANGELOG.md | 6 ++++++ Chart.yaml | 2 +- scripts/generate-helm-config-for-hcs.sh | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2b79811d..86ab03e222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.20.0 (Apr 24, 2020) + BREAKING CHANGES: * External Servers [[GH-430](https://github.com/hashicorp/consul-helm/pull/430)]: @@ -96,6 +98,10 @@ IMPROVEMENTS: * Default to the latest version of consul-k8s: hashicorp/consul-k8s:0.14.0 +BUG FIXES: + +* `tls-init-cleanup` can run even if pre-install fails [[GH-419](https://github.com/hashicorp/consul-helm/pull/419)]. + ## 0.19.0 (Apr 7, 2020) BREAKING CHANGES: diff --git a/Chart.yaml b/Chart.yaml index 272070a273..0e9929ca54 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.19.0 +version: 0.20.0 description: Install and configure Consul on Kubernetes. home: https://www.consul.io sources: diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh index f600479e52..ced92ed9b8 100755 --- a/scripts/generate-helm-config-for-hcs.sh +++ b/scripts/generate-helm-config-for-hcs.sh @@ -56,8 +56,8 @@ if grep -i "permission denied" <<< "$output"; then echo "ACL system already bootstrapped." echo -e "${RED}Please update 'global.acls.bootstrapToken' values in the generated Helm config to point to the Kubernetes secret containing the bootstrap token.${NOCOLOR}" echo -e "${RED}You can create a secret like so:${NOCOLOR}" - echo -e "${RED}kubectl create secret generic ${kube_resource_prefix}-bootstrap-token \${NOCOLOR}" - echo -e "${RED} --from-literal="token="${NOCOLOR}" + echo -e "${RED}kubectl create secret generic ${kube_resource_prefix}-bootstrap-token \ ${NOCOLOR}" + echo -e "${RED} --from-literal='token='${NOCOLOR}" elif grep -i "ACL support disabled" <<< "$output"; then echo -e "${RED}ACLs not enabled on this cluster.${NOCOLOR}" exit 1 From 1c866f24c97ba530f8f3deb04c51f3e62149e045 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 27 Apr 2020 10:09:23 -0700 Subject: [PATCH 341/739] client.join and externalServers.hosts can accept cloud auto-join with spaces --- templates/client-daemonset.yaml | 4 ++-- templates/server-acl-init-job.yaml | 2 +- test/unit/client-daemonset.bats | 29 +++++++++++++++++++++++++---- test/unit/helpers.bats | 14 ++++++++++++++ test/unit/server-acl-init-job.bats | 15 ++++++++++++++- 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index c8748f305e..c54468a524 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -207,12 +207,12 @@ spec: {{- end }} {{- if .Values.client.join }} {{- range $value := .Values.client.join }} - -retry-join={{ $value }} \ + -retry-join={{ quote $value }} \ {{- end }} {{- else }} {{- if .Values.server.enabled }} {{- range $index := until (.Values.server.replicas | int) }} - -retry-join=${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc \ + -retry-join="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ {{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 7849b96c2c..73a22c9fe3 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -99,7 +99,7 @@ spec: {{- if .Values.externalServers.enabled }} {{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} {{- range .Values.externalServers.hosts }} - -server-address={{ . }} \ + -server-address={{ quote . }} \ {{- end }} -server-port={{ .Values.externalServers.httpsPort }} \ {{- else }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index e4a3e84d1d..0879baeb70 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -77,12 +77,19 @@ load _helpers @test "client/DaemonSet: retry join gets populated by default" { cd `chart_dir` - local actual=$(helm template \ + local command=$(helm template \ -x templates/client-daemonset.yaml \ --set 'server.replicas=3' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command | any(contains("-retry-join"))' | tee /dev/stderr) + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } @@ -97,10 +104,24 @@ load _helpers . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].command') - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=1.1.1.1"))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"1.1.1.1\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"2.2.2.2\""))' | tee /dev/stderr) [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: can provide cloud auto-join string to client.join" { + cd `chart_dir` + local command=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'client.join[0]=provider=my-cloud config=val' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command') - local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=2.2.2.2"))' | tee /dev/stderr) + local actual=$(echo $command | jq -r ' . | any(contains("-retry-join=\"provider=my-cloud config=val\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index cff0dea249..fe9b2fd1a0 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -194,6 +194,20 @@ load _helpers [ "${actual}" = "true" ] } +@test "helper/consul.getAutoEncryptClientCA: can pass cloud auto-join string to server address via externalServers.hosts" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/tests/test-runner.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=provider=my-cloud config=val' \ + . | tee /dev/stderr | + yq '.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca").command | any(contains("-server-addr=\"provider=my-cloud config=val\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + @test "helper/consul.getAutoEncryptClientCA: can set TLS server name if externalServers.enabled is true" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 2296bf7e31..3337ff0d04 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -856,7 +856,20 @@ load _helpers --set 'externalServers.enabled=true' \ --set 'externalServers.hosts[0]=foo.com' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-server-address=foo.com"))' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].command | any(contains("-server-address=\"foo.com\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: can pass cloud auto-join string to server address via externalServers.hosts" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.enabled=false' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=provider=my-cloud config=val' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-server-address=\"provider=my-cloud config=val\""))' | tee /dev/stderr) [ "${actual}" = "true" ] } From 9473eb289ba692862a8d96650ac1eb8b1e28c5ff Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 27 Apr 2020 12:50:55 -0700 Subject: [PATCH 342/739] Update Chart description, app version --- Chart.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Chart.yaml b/Chart.yaml index 0e9929ca54..351a1bcffe 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,7 +1,8 @@ apiVersion: v1 name: consul version: 0.20.0 -description: Install and configure Consul on Kubernetes. +appVersion: 1.7.2 +description: Official HashiCorp Consul Chart home: https://www.consul.io sources: - https://github.com/hashicorp/consul From 138c76be197f20942cff04382d1fd92a8d8ebaf7 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 27 Apr 2020 15:40:42 -0700 Subject: [PATCH 343/739] Use OSS Consul image with HCS --- scripts/generate-helm-config-for-hcs.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh index ced92ed9b8..88c683eb05 100755 --- a/scripts/generate-helm-config-for-hcs.sh +++ b/scripts/generate-helm-config-for-hcs.sh @@ -81,7 +81,6 @@ kubectl create secret generic "${kube_resource_prefix}"-gossip-key --from-litera retry_join=$(jq -r --compact-output .retry_join consul.json) kube_api_server=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$(kubectl config current-context)\")].cluster.server}") -consul_version=$(echo "${cluster_resource}" | jq -r .properties.consulInitialVersion | cut -d'v' -f2) echo echo -e "${YELLOW}-> Writing Helm config to config.yaml${NOCOLOR}" @@ -89,7 +88,6 @@ cat > config.yaml << EOF global: enabled: false name: consul - image: hashicorp/consul-enterprise:${consul_version}-ent datacenter: $(jq -r .datacenter consul.json) acls: manageSystemACLs: true From 0d152218a066472cebb4376976edc59547f56b11 Mon Sep 17 00:00:00 2001 From: Alvin Huang <17609145+alvin-huang@users.noreply.github.com> Date: Mon, 27 Apr 2020 18:29:17 -0400 Subject: [PATCH 344/739] add API trigger for helm charts index --- .circleci/config.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e32fcfd182..4274acc6e2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,6 +38,20 @@ jobs: terraform destroy -auto-approve when: always + update-helm-charts-index: + docker: + - image: circleci/golang:latest + steps: + - run: + name: update helm-charts index + command: | + curl --show-error --silent --fail --user "${CIRCLE_TOKEN}:" \ + -X POST \ + -H 'Content-Type: application/json' \ + -H 'Accept: application/json' \ + -d "{\"branch\": \"master\",\"parameters\":{\"SOURCE_REPO\": \"${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}\",\"SOURCE_TAG\": \"${CIRCLE_TAG}\"}}" \ + "${CIRCLE_ENDPOINT}/${CIRCLE_PROJECT}/pipeline" + workflows: version: 2 test: @@ -49,3 +63,12 @@ workflows: filters: branches: only: master + update-helm-charts-index: + jobs: + - update-helm-charts-index: + context: helm-charts-trigger + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ From a1a791b740d8e999d5157aa81398c8d7ee013b29 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Mon, 27 Apr 2020 16:19:43 -0700 Subject: [PATCH 345/739] Release 0.20.1 --- CHANGELOG.md | 8 ++++++++ Chart.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ab03e222..8254614310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ## Unreleased +## 0.20.1 (Apr 27, 2020) + +BUG FIXES + +* Fix a bug where `client.join` and `externalServers.hosts` values containing spaces are + not quoted properly, for example, when providing [cloud auto-join](https://www.consul.io/docs/agent/cloud-auto-join.html) strings + [[GH-435](https://github.com/hashicorp/consul-helm/pull/435)]. + ## 0.20.0 (Apr 24, 2020) BREAKING CHANGES: diff --git a/Chart.yaml b/Chart.yaml index 351a1bcffe..6c363b1862 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: consul -version: 0.20.0 +version: 0.20.1 appVersion: 1.7.2 description: Official HashiCorp Consul Chart home: https://www.consul.io From 74bb451b795f90d2299ab8b5f0ad1e72ee33da1d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 30 Apr 2020 15:18:16 -0700 Subject: [PATCH 346/739] Set default mesh-gateway service name to 'mesh-gateway' --- templates/mesh-gateway-deployment.yaml | 4 ++-- values.yaml | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index da9ca9e4d6..b800315979 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -159,7 +159,7 @@ spec: cat > /consul/service/service.hcl << EOF service { kind = "mesh-gateway" - name = "{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}" + name = "{{ .Values.meshGateway.consulServiceName }}" {{- if .Values.global.federation }} {{- if .Values.global.federation.enabled }} meta { @@ -295,7 +295,7 @@ spec: lifecycle: preStop: exec: - command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ default "mesh-gateway" .Values.meshGateway.consulServiceName }}\""] + command: ["/bin/sh", "-ec", "/consul-bin/consul services deregister -id=\"{{ .Values.meshGateway.consulServiceName }}\""] # lifecycle-sidecar ensures the mesh gateway is always registered with # the local Consul agent, even if it loses the initial registration. diff --git a/values.yaml b/values.yaml index 50fb602c44..5ec186b30c 100644 --- a/values.yaml +++ b/values.yaml @@ -924,10 +924,11 @@ meshGateway: # dnsPolicy to use. dnsPolicy: null - # Override the default 'mesh-gateway' service name registered in Consul. - # Cannot be used if global.acls.manageSystemACLs is true since the ACL token + # Consul service name for the mesh gateways. + # Cannot be set to anything other than "mesh-gateway" if + # global.acls.manageSystemACLs is true since the ACL token # generated is only for the name 'mesh-gateway'. - consulServiceName: "" + consulServiceName: "mesh-gateway" # Port that the gateway will run on inside the container. containerPort: 8443 From 47ef1f16e1a0a685544803e8daf60b37bdf9d186 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 30 Apr 2020 17:22:17 -0700 Subject: [PATCH 347/739] New create-federation-secret job This job runs on post-install/upgrade and creates a Kubernetes secret that can be exported into secondary datacenters. The secondary datacenters will use the secret to federate with the primary. --- templates/create-federation-secret-job.yaml | 130 ++++++++++ ...e-federation-secret-podsecuritypolicy.yaml | 40 +++ templates/create-federation-secret-role.yaml | 49 ++++ .../create-federation-secret-rolebinding.yaml | 23 ++ ...eate-federation-secret-serviceaccount.yaml | 22 ++ templates/mesh-gateway-deployment.yaml | 2 - templates/server-acl-init-clusterrole.yaml | 2 +- templates/server-acl-init-job.yaml | 1 + templates/server-statefulset.yaml | 4 +- test/unit/create-federation-secret-job.bats | 244 ++++++++++++++++++ ...e-federation-secret-podsecuritypolicy.bats | 41 +++ test/unit/create-federation-secret-role.bats | 63 +++++ .../create-federation-secret-rolebinding.bats | 26 ++ ...eate-federation-secret-serviceaccount.bats | 51 ++++ test/unit/mesh-gateway-deployment.bats | 1 + test/unit/server-acl-init-job.bats | 9 + test/unit/server-statefulset.bats | 12 + values.yaml | 21 ++ 18 files changed, 736 insertions(+), 5 deletions(-) create mode 100644 templates/create-federation-secret-job.yaml create mode 100644 templates/create-federation-secret-podsecuritypolicy.yaml create mode 100644 templates/create-federation-secret-role.yaml create mode 100644 templates/create-federation-secret-rolebinding.yaml create mode 100644 templates/create-federation-secret-serviceaccount.yaml create mode 100644 test/unit/create-federation-secret-job.bats create mode 100644 test/unit/create-federation-secret-podsecuritypolicy.bats create mode 100644 test/unit/create-federation-secret-role.bats create mode 100644 test/unit/create-federation-secret-rolebinding.bats create mode 100644 test/unit/create-federation-secret-serviceaccount.bats diff --git a/templates/create-federation-secret-job.yaml b/templates/create-federation-secret-job.yaml new file mode 100644 index 0000000000..f513b159a8 --- /dev/null +++ b/templates/create-federation-secret-job.yaml @@ -0,0 +1,130 @@ +{{- if .Values.global.federation.createFederationSecret }} +{{- if not .Values.global.federation.enabled }}{{ fail "global.federation.enabled must be true when global.federation.createFederationSecret is true" }}{{ end }} +{{- if and (not .Values.global.acls.createReplicationToken) (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }}{{ fail "global.acls.createReplicationToken must be true when global.acls.manageSystemACLs is true because the federation secret must include the replication token" }}{{ end }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + {{- /* Hook weight needs to be 1 so that the service account is provisioned first */}} + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "consul.hashicorp.com/connect-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-create-federation-secret + volumes: + {{- /* We can assume tls is enabled because there is a check in server-statefulset + that requires tls to be enabled if federation is enabled. */}} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-ca-key + secret: + {{- if .Values.global.tls.caKey.secretName }} + secretName: {{ .Values.global.tls.caKey.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-key + {{- end }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key + {{- /* We must incude both auto-encrypt and server CAs because we make API calls to the local + Consul client (requiring the auto-encrypt CA) but the secret generated must include the server CA */}} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + - name: gossip-encryption-key + secret: + secretName: {{ .Values.global.gossipEncryption.secretName }} + items: + - key: {{ .Values.global.gossipEncryption.secretKey }} + path: gossip.key + {{- end }} + + {{- if .Values.global.tls.enableAutoEncrypt }} + initContainers: + {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} + {{- end }} + + containers: + - name: create-federation-secret + image: "{{ .Values.global.imageK8S }}" + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + {{- if .Values.global.tls.enableAutoEncrypt }} + value: /consul/tls/client/ca/tls.crt + {{- else }} + value: /consul/tls/ca/tls.crt + {{- end }} + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + - name: consul-ca-key + mountPath: /consul/tls/server/ca + readOnly: true + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + mountPath: /consul/tls/client/ca + readOnly: true + {{- end }} + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + - name: gossip-encryption-key + mountPath: /consul/gossip + readOnly: true + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s create-federation-secret \ + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + -gossip-key-file=/consul/gossip/gossip.key \ + {{- end }} + {{- if .Values.global.acls.createReplicationToken }} + -export-replication-token=true \ + {{- end }} + -mesh-gateway-service-name={{ .Values.meshGateway.consulServiceName }} \ + -k8s-namespace="${NAMESPACE}" \ + -resource-prefix="{{ template "consul.fullname" . }}" \ + -server-ca-cert-file=/consul/tls/ca/tls.crt \ + -server-ca-key-file=/consul/tls/server/ca/tls.key +{{- end }} diff --git a/templates/create-federation-secret-podsecuritypolicy.yaml b/templates/create-federation-secret-podsecuritypolicy.yaml new file mode 100644 index 0000000000..daaf405230 --- /dev/null +++ b/templates/create-federation-secret-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if .Values.global.enablePodSecurityPolicies }} +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + - 'emptyDir' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/templates/create-federation-secret-role.yaml b/templates/create-federation-secret-role.yaml new file mode 100644 index 0000000000..04e47bca87 --- /dev/null +++ b/templates/create-federation-secret-role.yaml @@ -0,0 +1,49 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +rules: + {{/* Must have separate rule for create secret permissions vs update because + can't set resourceNames for create (https://github.com/kubernetes/kubernetes/issues/80295) */}} + - apiGroups: [""] + resources: + - secrets + verbs: + - create + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-federation + verbs: + - update + {{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-acl-replication-acl-token + verbs: + - get + {{- end }} + {{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-create-federation-secret + {{- end }} +{{- end }} diff --git a/templates/create-federation-secret-rolebinding.yaml b/templates/create-federation-secret-rolebinding.yaml new file mode 100644 index 0000000000..3db8e7cb06 --- /dev/null +++ b/templates/create-federation-secret-rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-create-federation-secret +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-create-federation-secret +{{- end }} diff --git a/templates/create-federation-secret-serviceaccount.yaml b/templates/create-federation-secret-serviceaccount.yaml new file mode 100644 index 0000000000..e398ec69c4 --- /dev/null +++ b/templates/create-federation-secret-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index b800315979..30f3bb1e61 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -160,13 +160,11 @@ spec: service { kind = "mesh-gateway" name = "{{ .Values.meshGateway.consulServiceName }}" - {{- if .Values.global.federation }} {{- if .Values.global.federation.enabled }} meta { consul-wan-federation = "1" } {{- end }} - {{- end }} port = {{ .Values.meshGateway.containerPort }} address = "${POD_IP}" tagged_addresses { diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 84cd91d794..cd95b367da 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -45,4 +45,4 @@ rules: - use {{- end }} {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 73a22c9fe3..689a5db22c 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,6 +1,7 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if and .Values.global.acls.createReplicationToken (not (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs)) }}{{ fail "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" }}{{ end -}} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} {{- /* We don't render this job when server.updatePartition > 0 because that means a server rollout is in progress and this job won't complete unless diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 3c057bfb97..1fa13ed828 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -1,5 +1,7 @@ # StatefulSet to run the actual Consul server cluster. {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if and .Values.global.federation.enabled (not .Values.global.tls.enabled) }}{{ fail "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" }}{{ end }} +{{- if and .Values.global.federation.enabled (not .Values.meshGateway.enabled) }}{{ fail "If global.federation.enabled is true, meshGateway.enabled must be true because mesh gateways are required for federation" }}{{ end }} apiVersion: apps/v1 kind: StatefulSet metadata: @@ -168,11 +170,9 @@ spec: {{- if .Values.server.connect }} -hcl="connect { enabled = true }" \ {{- end }} - {{- if .Values.global.federation }} {{- if .Values.global.federation.enabled }} -hcl="connect { enable_mesh_gateway_wan_federation = true }" \ {{- end }} - {{- end }} {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} -hcl="acl { tokens { agent = \"${ACL_REPLICATION_TOKEN}\", replication = \"${ACL_REPLICATION_TOKEN}\" } }" \ {{- end }} diff --git a/test/unit/create-federation-secret-job.bats b/test/unit/create-federation-secret-job.bats new file mode 100644 index 0000000000..c0db8a035f --- /dev/null +++ b/test/unit/create-federation-secret-job.bats @@ -0,0 +1,244 @@ +#!/usr/bin/env bats + +load _helpers + +@test "createFederationSecet/Job: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecet/Job: fails when global.federation.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.createFederationSecret=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.federation.enabled must be true when global.federation.createFederationSecret is true" ]] +} + +# NOTE: This error actually comes from server-statefulset but we test it here +# too because this job requires TLS to be enabled. +@test "createFederationSecet/Job: fails when global.tls.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'global.federation.createFederationSecret=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" ]] +} + +# NOTE: This error actually comes from server-acl-init but we test it here +# too because this job requires that ACLs are enabled when createReplicationToken is true. +@test "createFederationSecet/Job: fails when global.acls.createReplicationToken is true but global.acls.manageSystemACLs is false" { + cd `chart_dir` + run helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.acls.createReplicationToken=true' \ + --set 'global.federation.createFederationSecret=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" ]] +} + +@test "createFederationSecet/Job: fails when global.acls.createReplicationToken is false but global.acls.manageSystemACLs is true" { + cd `chart_dir` + run helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.acls.createReplicationToken=false' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.federation.createFederationSecret=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.acls.createReplicationToken must be true when global.acls.manageSystemACLs is true because the federation secret must include the replication token" ]] +} + +@test "createFederationSecet/Job: mounts auto-created ca secrets by default" { + cd `chart_dir` + local volumes=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes' | tee /dev/stderr ) + + local actual + + # test it uses the auto-generated ca secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-cert" and .secret.secretName=="release-name-consul-ca-cert")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the correct secret key for the auto-generated ca secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-cert" and .secret.items[0].key =="tls.crt")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the auto-generated ca key secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-key" and .secret.secretName=="release-name-consul-ca-key")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the correct secret key for the auto-generated ca key secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-key" and .secret.items[0].key =="tls.key")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.tls + +@test "createFederationSecet/Job: mounts caCert secrets when set manually" { + cd `chart_dir` + local volumes=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=custom-ca-cert' \ + --set 'global.tls.caCert.secretKey=customKey' \ + --set 'global.tls.caKey.secretName=custom-ca-key' \ + --set 'global.tls.caKey.secretKey=customKey2' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr | + yq '.spec.template.spec.volumes' | tee /dev/stderr ) + + local actual + + # test it uses the custom ca cert secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-cert" and .secret.secretName=="custom-ca-cert")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the custom ca cert secret key + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-cert" and .secret.items[0].key =="customKey")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the custom ca key secret + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-key" and .secret.secretName=="custom-ca-key")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it uses the custom ca key secret key + actual=$(echo $volumes | yq 'map(select(.name=="consul-ca-key" and .secret.items[0].key =="customKey2")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "createFederationSecet/Job: auto-encrypt disabled" { + cd `chart_dir` + local obj=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr) + + local actual + + # test it doesn't have any init containers + actual=$(echo "$obj" | yq '.spec.template.spec.initContainers | length == 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it sets CONSUL_CACERT to the server ca cert + actual=$(echo "$obj" | yq '.spec.template.spec.containers[0].env | map(select(.name == "CONSUL_CACERT" and .value == "/consul/tls/ca/tls.crt")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "createFederationSecet/Job: auto-encrypt enabled" { + cd `chart_dir` + local obj=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr) + + local actual + + # test it has the auto-encrypt volume + actual=$(echo "$obj" | yq '.spec.template.spec.volumes | map(select(.name == "consul-auto-encrypt-ca-cert")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it adds the init container + actual=$(echo "$obj" | yq '.spec.template.spec.initContainers | map(select(.name == "get-auto-encrypt-client-ca")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it sets CONSUL_CACERT to the auto-encrypt ca cert + actual=$(echo "$obj" | yq '.spec.template.spec.containers[0].env | map(select(.name == "CONSUL_CACERT" and .value == "/consul/tls/client/ca/tls.crt")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.gossipEncryption + +@test "createFederationSecet/Job: gossip encryption key set" { + cd `chart_dir` + local obj=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.gossipEncryption.secretName=gossip-secret' \ + --set 'global.gossipEncryption.secretKey=key' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr) + + local actual + + # test it mounts the secret + actual=$(echo "$obj" | yq '.spec.template.spec.volumes | map(select(.name == "gossip-encryption-key" and .secret.secretName == "gossip-secret" and .secret.items[0].key == "key")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + # test it sets the -gossip-key-file flag + actual=$(echo "$obj" | yq '.spec.template.spec.containers[0].command | any(contains("-gossip-key-file"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.acls.createReplicationToken + +@test "createFederationSecet/Job: global.acls.createReplicationToken=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.createReplicationToken=true' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-export-replication-token=true"))') + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# meshGateway.consulServiceName + +@test "createFederationSecet/Job: sets -mesh-gateway-service-name to meshGateway.consulServiceName" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.consulServiceName=my-service-name' \ + --set 'global.federation.createFederationSecret=true' . \ + . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-mesh-gateway-service-name=my-service-name"))') + [ "${actual}" = "true" ] +} diff --git a/test/unit/create-federation-secret-podsecuritypolicy.bats b/test/unit/create-federation-secret-podsecuritypolicy.bats new file mode 100644 index 0000000000..5832424aeb --- /dev/null +++ b/test/unit/create-federation-secret-podsecuritypolicy.bats @@ -0,0 +1,41 @@ +#!/usr/bin/env bats + +load _helpers + +@test "createFederationSecret/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecret/PodSecurityPolicy: disabled when global.federation.createFederationSecret=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-podsecuritypolicy.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecret/PodSecurityPolicy: enabled with global.federation.createFederationSecret=true and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-podsecuritypolicy.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/create-federation-secret-role.bats b/test/unit/create-federation-secret-role.bats new file mode 100644 index 0000000000..6c18a24867 --- /dev/null +++ b/test/unit/create-federation-secret-role.bats @@ -0,0 +1,63 @@ +#!/usr/bin/env bats + +load _helpers + +@test "createFederationSecret/Role: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-role.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecret/Role: enabled with global.federation.createFederationSecret=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-role.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.acls.manageSystemACLs + +@test "createFederationSecret/Role: allows read access for replication token with global.acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-role.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.createReplicationToken=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resourceNames[0] == "release-name-consul-acl-replication-acl-token")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +#-------------------------------------------------------------------- +# global.enablePodSecurityPolicies + +@test "createFederationSecret/Role: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-role.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -r '.rules | map(select(.resources[0] == "podsecuritypolicies")) | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} diff --git a/test/unit/create-federation-secret-rolebinding.bats b/test/unit/create-federation-secret-rolebinding.bats new file mode 100644 index 0000000000..c80e66b050 --- /dev/null +++ b/test/unit/create-federation-secret-rolebinding.bats @@ -0,0 +1,26 @@ +#!/usr/bin/env bats + +load _helpers + +@test "createFederationSecret/RoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-rolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecret/RoleBinding: enabled with global.createFederationSecret=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-rolebinding.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/test/unit/create-federation-secret-serviceaccount.bats b/test/unit/create-federation-secret-serviceaccount.bats new file mode 100644 index 0000000000..81c2d66034 --- /dev/null +++ b/test/unit/create-federation-secret-serviceaccount.bats @@ -0,0 +1,51 @@ +#!/usr/bin/env bats + +load _helpers + +@test "createFederationSecret/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "createFederationSecret/ServiceAccount: enabled with global.federation.createFederationSecret=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/create-federation-secret-serviceaccount.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "createFederationSecret/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/create-federation-secret-serviceaccount.yaml \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -r '.imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 38389a9f71..1404686c9f 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -732,6 +732,7 @@ EOF --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 3337ff0d04..34e987250f 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -86,6 +86,15 @@ load _helpers [[ "$output" =~ "only one of server.enabled or externalServers.enabled can be set" ]] } +@test "serverACLInit/Job: fails if createReplicationToken=true but manageSystemACLs=false" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.createReplicationToken=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" ]] +} + @test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 8809e2c440..92dbb7e2d4 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -680,11 +680,23 @@ load _helpers #-------------------------------------------------------------------- # global.federation.enabled +@test "server/StatefulSet: fails when federation.enabled=true and tls.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/server-statefulset.yaml \ + --set 'global.federation.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" ]] +} + @test "server/StatefulSet: mesh gateway federation enabled when federation.enabled=true" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ --set 'global.federation.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | join(" ") | contains("connect { enable_mesh_gateway_wan_federation = true }")' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/values.yaml b/values.yaml index 5ec186b30c..a1b2769410 100644 --- a/values.yaml +++ b/values.yaml @@ -198,6 +198,27 @@ global: secretName: null secretKey: null + # Settings related to federating with another Consul datacenter. + federation: + # Experimental: Currently this is only available in Consul 1.8.0-beta1. + # To use, set global.image: "consul:1.8.0-beta1". + # If enabled, this datacenter will be federation-capable. Only federation + # through mesh gateways is supported. + # Mesh gateways and servers will be configured to allow federation. + # Requires global.tls.enabled, meshGateway.enabled and connectInject.enabled + # to be true. + enabled: false + + # If true, the chart will create a Kubernetes secret that can be imported + # into secondary datacenters so they can federate with this datacenter. The + # secret contains all the information secondary datacenters need to contact + # and authenticate with this datacenter. This should only be set to true + # in your primary datacenter. The secret name is + # -federation (if setting global.name), otherwise + # -consul-federation. + # Requires consul-k8s 0.15.0+. + createFederationSecret: false + # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to # the Kube cluster. From 7e248cfd86c7d9dd811a9d2ff322d818c1e07d42 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 11 May 2020 13:26:20 -0700 Subject: [PATCH 348/739] Use same master version as node version Otherwise we get the error ``` Error: node_version and min_master_version must be set to equivalent values on create ``` --- test/terraform/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/terraform/main.tf b/test/terraform/main.tf index 68fd74fd8e..8204d81a9a 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -21,7 +21,7 @@ resource "google_container_cluster" "cluster" { initial_node_count = 3 location = var.zone min_master_version = data.google_container_engine_versions.main.latest_master_version - node_version = data.google_container_engine_versions.main.latest_node_version + node_version = data.google_container_engine_versions.main.latest_master_version } resource "null_resource" "kubectl" { From 351595a27da9ba7c5c476cde3c77186168dcc38d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 12 May 2020 10:49:32 -0700 Subject: [PATCH 349/739] Fix missing NODE_NAME env var --- templates/mesh-gateway-deployment.yaml | 2 +- test/unit/mesh-gateway-deployment.bats | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 30f3bb1e61..a3422ad4c3 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -235,7 +235,7 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP - {{- if .Values.meshGateway.wanAddress.useNodeName }} + {{- if eq .Values.meshGateway.wanAddress.source "NodeName" }} - name: NODE_NAME valueFrom: fieldRef: diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 1404686c9f..09a0854fc5 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -875,12 +875,18 @@ EOF @test "meshGateway/Deployment: service-init init container wanAddress.source=NodeName" { cd `chart_dir` - local actual=$(helm template \ + local obj=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'meshGateway.wanAddress.source=NodeName' \ - . | tee /dev/stderr | + . | tee /dev/stderr) + + local actual=$(echo "$obj" | + yq -r '.spec.template.spec.containers[0].env | map(select(.name == "NODE_NAME")) | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$obj" | yq -r '.spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) exp='WAN_ADDR="${NODE_NAME}" From 2090d890ce7ce2f48b09eeee8d574c2d1cf67e37 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 12 May 2020 12:56:08 -0700 Subject: [PATCH 350/739] Restrict permissions for the server-acl-init job Now that the server-acl-init job takes server DNS names as input, we don't need permissions to list pods and get statefulsets. Additionally, only set one of connectInject.enabled to true in the generated config for HCS since we don't recommend enabling both connectInject and syncCatalog. --- scripts/generate-helm-config-for-hcs.sh | 2 -- templates/server-acl-init-clusterrole.yaml | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/scripts/generate-helm-config-for-hcs.sh b/scripts/generate-helm-config-for-hcs.sh index 88c683eb05..e2504b9573 100755 --- a/scripts/generate-helm-config-for-hcs.sh +++ b/scripts/generate-helm-config-for-hcs.sh @@ -117,8 +117,6 @@ client: join: ${retry_join} connectInject: enabled: true -syncCatalog: - enabled: true EOF echo diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index cd95b367da..3007661caf 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -11,22 +11,12 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} rules: - - apiGroups: [""] - resources: - - pods - verbs: - - list - apiGroups: [""] resources: - secrets verbs: - create - get - - apiGroups: ["apps"] - resources: - - statefulsets - verbs: - - get {{- if .Values.connectInject.enabled }} - apiGroups: [""] resources: From 566d4876a808a9bc67896004c3d7a76cbd9c5325 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 12 May 2020 16:08:33 -0700 Subject: [PATCH 351/739] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8254614310..b67643896a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased +IMPROVEMENTS + +* ACLs: Restrict permissions for the `server-acl-init` job [[GH-454](https://github.com/hashicorp/consul-helm/pull/454)]. + ## 0.20.1 (Apr 27, 2020) BUG FIXES From c7bd88aeef889c35079fdb308070e98d5988f9ed Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 13 May 2020 09:31:24 -0700 Subject: [PATCH 352/739] 0.21.0 release * changelog * bump default Consul image to 1.7.3 --- CHANGELOG.md | 13 +++++++++++++ Chart.yaml | 4 ++-- values.yaml | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b67643896a..eedd5dc391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,22 @@ ## Unreleased +FEATURES + +* Add new Helm value `global.federation.createFederationSecret` that will + create a Kubernetes secret in primary datacenters that can be exported to secondary + datacenters to ease federation ([GH-447](https://github.com/hashicorp/consul-helm/pull/447)). + IMPROVEMENTS +* Default Consul Docker image is now `consul:1.7.3`. +* Default consul-k8s Docker image is now `hashicorp/consul-k8s:0.15.0`. * ACLs: Restrict permissions for the `server-acl-init` job [[GH-454](https://github.com/hashicorp/consul-helm/pull/454)]. +BUG FIXES + +* Fix missing NODE_NAME environment variable when setting `meshGateway.wanAddress.source=NodeName` + [[GH-453](https://github.com/hashicorp/consul-helm/pull/453)]. + ## 0.20.1 (Apr 27, 2020) BUG FIXES diff --git a/Chart.yaml b/Chart.yaml index 6c363b1862..a432f58fa7 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: consul -version: 0.20.1 -appVersion: 1.7.2 +version: 0.21.0 +appVersion: 1.7.3 description: Official HashiCorp Consul Chart home: https://www.consul.io sources: diff --git a/values.yaml b/values.yaml index a1b2769410..47c8aeafeb 100644 --- a/values.yaml +++ b/values.yaml @@ -30,7 +30,7 @@ global: # image: "consul:1.5.0" # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" - image: "consul:1.7.2" + image: "consul:1.7.3" # array of objects containing image pull secret names that will be applied to # each service account. @@ -53,7 +53,7 @@ global: # If using acls.manageSystemACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. # If using Consul Enterprise namespaces, must be >= 0.12. - imageK8S: "hashicorp/consul-k8s:0.14.0" + imageK8S: "hashicorp/consul-k8s:0.15.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running From d1ff2a131a5c3f34f98eda4e2f0d4ac915777b8c Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 13 May 2020 12:24:10 -0700 Subject: [PATCH 353/739] Update CHANGELOG.md Co-authored-by: Iryna Shustava --- CHANGELOG.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eedd5dc391..606ecc85e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,23 @@ ## Unreleased +## 0.21.0 (May 14, 2020) + FEATURES +* Add experimental support for multi-datacenter federation via + + ```yaml + global: + federation: + enabled: true + ``` + + This requires Consul 1.8.0+ (which as of this release is only available as + a beta. To use the beta, set `global.image: consul:1.8.0-beta1`) + * Add new Helm value `global.federation.createFederationSecret` that will create a Kubernetes secret in primary datacenters that can be exported to secondary - datacenters to ease federation ([GH-447](https://github.com/hashicorp/consul-helm/pull/447)). + datacenters to help bootstrap secondary clusters for federation ([GH-447](https://github.com/hashicorp/consul-helm/pull/447)). IMPROVEMENTS @@ -14,7 +27,7 @@ IMPROVEMENTS BUG FIXES -* Fix missing NODE_NAME environment variable when setting `meshGateway.wanAddress.source=NodeName` +* Fix missing `NODE_NAME` environment variable when setting `meshGateway.wanAddress.source=NodeName` [[GH-453](https://github.com/hashicorp/consul-helm/pull/453)]. ## 0.20.1 (Apr 27, 2020) From 75f10d5928cd8fe0edd1139c730c0f01cbde84f9 Mon Sep 17 00:00:00 2001 From: David Yu Date: Tue, 19 May 2020 13:40:55 -0700 Subject: [PATCH 354/739] Updated README with Helm repo instructions (#461) * Updated README with Helm repo instructions * Update README.md Co-authored-by: Luke Kysow <1034429+lkysow@users.noreply.github.com> Co-authored-by: Luke Kysow <1034429+lkysow@users.noreply.github.com> --- README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ea999cc7d4..90cf2296f9 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,23 @@ The versions required are: ## Usage -For now, we do not host a chart repository. To use the charts, you must -download this repository and unpack it into a directory. Either -[download a tagged release](https://github.com/hashicorp/consul-helm/releases) or -use `git checkout` to a tagged release. -Assuming this repository was unpacked into the directory `consul-helm`, the chart can -then be installed directly: - - helm install ./consul-helm +Detailed installatiion instructions for Consul on Kubernetes are found [here](https://www.consul.io/docs/k8s/installation/overview). + +Add the HashiCorp Helm Repository: + + $ helm repo add hashicorp https://helm.releases.hashicorp.com + hashicorp" has been added to your repositories + +Ensure you have access to the consul chart: + + $ helm search repo hashicorp/consul + NAME CHART VERSION APP VERSION DESCRIPTION + hashicorp/consul 0.20.1 1.7.2 Official HashiCorp Consul Chart + +Now you're ready to install Consul! To install Consul with the default configuration using Helm 3 run: + + $ helm install consul hashicorp/consul --set global.name=consul + NAME: consul Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the From e73f203e2aebc294c5421b0040700ffea0c5497b Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 19 May 2020 17:29:31 -0700 Subject: [PATCH 355/739] Update README.md (#462) --- README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/README.md b/README.md index 90cf2296f9..7ce3a625d4 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,7 @@ use Consul with Kubernetes, please see the [Consul and Kubernetes documentation](https://www.consul.io/docs/platform/k8s/index.html). ## Prerequisites - -To use the charts here, [Helm](https://helm.sh/) must be installed in your -Kubernetes cluster. Setting up Kubernetes and Helm and is outside the scope -of this README. Please refer to the Kubernetes and Helm documentation. - -The versions required are: - - * **Helm 2.10+** - This is the earliest version of Helm tested. It is possible - it works with earlier versions but this chart is untested for those versions. + * **Helm 2.10+ or Helm 3.0+** * **Kubernetes 1.9+** - This is the earliest version of Kubernetes tested. It is possible that this chart works with earlier versions but it is untested. From 6fe0c3237734ad1568f3778aba2b2e2b042c689b Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 20 May 2020 13:23:35 -0700 Subject: [PATCH 356/739] Remove meshGateway.enableHealthChecks This was a workaround for a bug fixed in Consul 1.6.2. --- CHANGELOG.md | 6 ++++++ templates/mesh-gateway-deployment.yaml | 2 -- test/unit/mesh-gateway-deployment.bats | 17 ----------------- values.yaml | 5 ----- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 606ecc85e6..d189451753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Unreleased +BREAKING CHANGES: + +* Mesh Gateway: `meshGateway.enableHealthChecks` is no longer supported. This config + option was to work around an issue where mesh gateways would not listen on their + bind ports until a Connect service was registered. This issue was fixed in Consul 1.6.2. ([GH-464](https://github.com/hashicorp/consul-helm/pull/464)) + ## 0.21.0 (May 14, 2020) FEATURES diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index a3422ad4c3..69caf7a33e 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -266,7 +266,6 @@ spec: - connect - envoy - -mesh-gateway - {{- if .Values.meshGateway.enableHealthChecks }} livenessProbe: tcpSocket: port: {{ .Values.meshGateway.containerPort }} @@ -283,7 +282,6 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 - {{- end }} ports: - name: gateway containerPort: {{ .Values.meshGateway.containerPort }} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 09a0854fc5..1e8cb3de66 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -402,23 +402,6 @@ key2: value2' \ [ "${readiness}" = "true" ] } -@test "meshGateway/Deployment: can disable healthchecks" { - cd `chart_dir` - local actual=$(helm template \ - -x templates/mesh-gateway-deployment.yaml \ - --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ - --set 'meshGateway.enableHealthChecks=false' \ - . | tee /dev/stderr \ - | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) - - local liveness=$(echo "${actual}" | yq -r '.livenessProbe | length > 0' | tee /dev/stderr) - [ "${liveness}" = "false" ] - local readiness=$(echo "${actual}" | yq -r '.readinessProbe | length > 0' | tee /dev/stderr) - [ "${readiness}" = "false" ] -} - #-------------------------------------------------------------------- # hostPort diff --git a/values.yaml b/values.yaml index 47c8aeafeb..d6f9e96b9f 100644 --- a/values.yaml +++ b/values.yaml @@ -963,11 +963,6 @@ meshGateway: # agent. hostPort: null - # If there are no connect-enabled services running, then the gateway - # will fail health checks. You may disable health checks as a temporary - # workaround. - enableHealthChecks: true - resources: | requests: memory: "128Mi" From 4f7a3672dd77f355ff48bac01cc6121625edaa71 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Tue, 26 May 2020 19:00:18 -0700 Subject: [PATCH 357/739] Fix typo in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ce3a625d4..030675d4fb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This repository contains the official HashiCorp Helm chart for installing and configuring Consul on Kubernetes. This chart supports multiple use -cases of Consul on Kubernetes depending on the values provided. +cases of Consul on Kubernetes, depending on the values provided. For full documentation on this Helm chart along with all the ways you can use Consul with Kubernetes, please see the @@ -16,7 +16,7 @@ use Consul with Kubernetes, please see the ## Usage -Detailed installatiion instructions for Consul on Kubernetes are found [here](https://www.consul.io/docs/k8s/installation/overview). +Detailed installation instructions for Consul on Kubernetes are found [here](https://www.consul.io/docs/k8s/installation/overview). Add the HashiCorp Helm Repository: From c6053f90e3b0041f98b7e7e7e7db16196880d85d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 28 May 2020 10:50:09 -0700 Subject: [PATCH 358/739] Update values docs to match website --- values.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/values.yaml b/values.yaml index 47c8aeafeb..721f0aa355 100644 --- a/values.yaml +++ b/values.yaml @@ -861,7 +861,7 @@ meshGateway: # If mesh gateways are enabled, a Deployment will be created that runs # gateways and Consul Connect will be configured to use gateways. # See https://www.consul.io/docs/connect/mesh_gateway.html - # Requirements: consul >= 1.6.0 and consul-k8s >= 0.9.0 if using + # Requirements: consul 1.6.0+ and consul-k8s 0.15.0+ if using # global.acls.manageSystemACLs. enabled: false @@ -922,8 +922,8 @@ meshGateway: # The targetPort will be set to meshGateway.containerPort. port: 443 - # Optionally hardcode the nodePort of the service if using type: NodePort. - # If not set and using type: NodePort, Kubernetes will automatically assign + # Optionally hardcode the nodePort of the service if using a NodePort service. + # If not set and using a NodePort service, Kubernetes will automatically assign # a port. nodePort: null From f3044d148e5937c7fa0e207f699e8377e28c35da Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 21 May 2020 12:57:16 -0700 Subject: [PATCH 359/739] Deprecate setting resources as string. --- CHANGELOG.md | 31 ++++++++++++++++++++++++++ templates/client-daemonset.yaml | 4 ++++ templates/mesh-gateway-deployment.yaml | 4 ++++ templates/server-statefulset.yaml | 4 ++++ test/unit/client-daemonset.bats | 17 +++++++++++--- test/unit/mesh-gateway-deployment.bats | 20 ++++++++++++++--- test/unit/server-statefulset.bats | 17 +++++++++++--- values.yaml | 19 ++++++++++------ 8 files changed, 100 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d189451753..193122f9ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,37 @@ BREAKING CHANGES: option was to work around an issue where mesh gateways would not listen on their bind ports until a Connect service was registered. This issue was fixed in Consul 1.6.2. ([GH-464](https://github.com/hashicorp/consul-helm/pull/464)) +DEPRECATIONS + +* Setting resources via YAML string is now deprecated. Instead, set directly as YAML. + This affects `client.resources`, `server.resources` and `meshGateway.resources`. + To set directly as YAML, simply remove the pipe (`|`) character that defines + the YAML as a string: + + Before: + ```yaml + client: + resources: | + requests: + memory: "128Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "500m" + ``` + + After: + ```yaml + client: + resources: + requests: + memory: "128Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "500m" + ``` + ## 0.21.0 (May 14, 2020) FEATURES diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index c54468a524..40949ee41a 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -295,7 +295,11 @@ spec: 2>/dev/null | grep -E '".+"' {{- if .Values.client.resources }} resources: + {{- if eq (typeOf .Values.client.resources) "string" }} {{ tpl .Values.client.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.client.resources | nindent 12 }} + {{- end }} {{- end }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} initContainers: diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 69caf7a33e..f1dcaeb48d 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -212,7 +212,11 @@ spec: image: {{ .Values.meshGateway.imageEnvoy | quote }} {{- if .Values.meshGateway.resources }} resources: + {{- if eq (typeOf .Values.meshGateway.resources) "string" }} {{ tpl .Values.meshGateway.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.meshGateway.resources | nindent 12 }} + {{- end }} {{- end }} volumeMounts: - name: consul-bin diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 1fa13ed828..55d9586e13 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -252,7 +252,11 @@ spec: timeoutSeconds: 5 {{- if .Values.server.resources }} resources: + {{- if eq (typeOf .Values.server.resources) "string" }} {{ tpl .Values.server.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.server.resources | nindent 12 }} + {{- end }} {{- end }} {{- if .Values.server.nodeSelector }} nodeSelector: diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 0879baeb70..9a15311367 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -163,10 +163,21 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ - --set 'client.resources=foo' \ + --set 'client.resources.foo=bar' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) - [ "${actual}" = "foo" ] + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + +# Test support for the deprecated method of setting a YAML string. +@test "client/DaemonSet: resources can be set with string" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.resources=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] } #-------------------------------------------------------------------- diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 1e8cb3de66..5eb5f8e906 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -297,10 +297,24 @@ key2: value2' \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ --set 'client.grpc=true' \ - --set 'meshGateway.resources=requests: yadayada' \ + --set 'meshGateway.resources.foo=bar' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].resources.requests' | tee /dev/stderr) - [ "${actual}" = "yadayada" ] + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + +# Test support for the deprecated method of setting a YAML string. +@test "meshGateway/Deployment: resources can be overridden with string" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'client.grpc=true' \ + --set 'meshGateway.resources=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] } #-------------------------------------------------------------------- diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 92dbb7e2d4..39a64f6a2e 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -96,10 +96,21 @@ load _helpers cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ - --set 'server.resources=foo' \ + --set 'server.resources.foo=bar' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) - [ "${actual}" = "foo" ] + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + +# Test support for the deprecated method of setting a YAML string. +@test "server/StatefulSet: resources can be set with string" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-statefulset.yaml \ + --set 'server.resources=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] } #-------------------------------------------------------------------- diff --git a/values.yaml b/values.yaml index 7c02e82cdf..9f3179ed6a 100644 --- a/values.yaml +++ b/values.yaml @@ -252,9 +252,10 @@ server: connect: true # Resource requests, limits, etc. for the server cluster placement. This - # should map directly to the value of the resources field for a PodSpec, - # formatted as a multi-line string. By default no direct resource request - # is made. + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + # NOTE: The use of a YAML string is deprecated. Instead, set directly as a + # YAML map. resources: null # updatePartition is used to control a careful rolling update of Consul @@ -411,9 +412,10 @@ client: exposeGossipPorts: false # Resource requests, limits, etc. for the client cluster placement. This - # should map directly to the value of the resources field for a PodSpec, - # formatted as a multi-line string. By default no direct resource request - # is made. + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + # NOTE: The use of a YAML string is deprecated. Instead, set directly as a + # YAML map. resources: null # extraConfig is a raw string of extra configuration to set with the @@ -963,7 +965,10 @@ meshGateway: # agent. hostPort: null - resources: | + # Resource settings for mesh gateway pods. + # NOTE: The use of a YAML string is deprecated. Instead, set directly as a + # YAML map. + resources: requests: memory: "128Mi" cpu: "250m" From cb7367a0689813e15cc36749177666d9b76dc199 Mon Sep 17 00:00:00 2001 From: Alvin Huang <17609145+alvin-huang@users.noreply.github.com> Date: Thu, 28 May 2020 16:42:29 -0400 Subject: [PATCH 360/739] check that git tag == chart tag on tagged releases --- .circleci/config.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4274acc6e2..3e1aa44609 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,7 @@ -version: 2 +version: 2.1 +orbs: + slack: circleci/slack@3.4.2 + jobs: unit: docker: @@ -42,6 +45,17 @@ jobs: docker: - image: circleci/golang:latest steps: + - checkout + - run: + name: verify Chart version matches tag version + command: | + GO111MODULE=on go get github.com/mikefarah/yq/v2 + git_tag=$(echo "${CIRCLE_TAG#v}") + chart_tag=$(yq r Chart.yaml version) + if [ "${git_tag}" != "${chart_tag}" ]; then + echo "chart version (${chart_tag}) did not match git version (${git_tag})" + exit 1 + fi - run: name: update helm-charts index command: | @@ -51,6 +65,9 @@ jobs: -H 'Accept: application/json' \ -d "{\"branch\": \"master\",\"parameters\":{\"SOURCE_REPO\": \"${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}\",\"SOURCE_TAG\": \"${CIRCLE_TAG}\"}}" \ "${CIRCLE_ENDPOINT}/${CIRCLE_PROJECT}/pipeline" + - slack/status: + fail_only: true + failure_message: "Failed to trigger an update to the helm charts index. Check the logs at: ${CIRCLE_BUILD_URL}" workflows: version: 2 From 17e1f704643f778df656318719c8c16011161c6d Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 1 Jun 2020 12:42:34 -0700 Subject: [PATCH 361/739] Add icon to chart.yaml --- Chart.yaml | 1 + assets/icon.png | Bin 0 -> 7981 bytes 2 files changed, 1 insertion(+) create mode 100644 assets/icon.png diff --git a/Chart.yaml b/Chart.yaml index a432f58fa7..04e4b6f3c9 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -4,6 +4,7 @@ version: 0.21.0 appVersion: 1.7.3 description: Official HashiCorp Consul Chart home: https://www.consul.io +icon: https://raw.githubusercontent.com/hashicorp/consul-helm/master/assets/icon.png sources: - https://github.com/hashicorp/consul - https://github.com/hashicorp/consul-helm diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0798b2445de59405c89614338a3276bfb36d832f GIT binary patch literal 7981 zcmaKRWlS7Ew>FDwad)@HU0RAS?y$I(;!@mQyDjcer1)ZsyE_zzMT!W|PYye4MuFuM(9h1=2Pt0+J6Gc^x zPl)vVNb$Q^W4_$090&4mc9favc4lPpY)*FeNIr_S6rGN00T#Ah!Whwjif_R2R4^(r z_g?qi(7jQ>MAH8qG>Vp-hHRqME)>ms!+m`&;&!KPB&(717wOaY3XB>ooP95ZQS|~K zG7<^wh+}z3`j6)v)5Dcy9%lXa+V5BPzd&(3tDGohV|}k_)$^qqEdSY%HeeXT82ks4ITC|Rb=FKOnL}heG+wJ998Zf5c z;z9KD>o!8DYG={Cbrqb;pjdi^DAUd;kzZS<2cQSGR*I9TnZX?AdD7fKpPiv1#(3+d z^y5pSBp;`->}s9gN>q5BR;lIh0ip*x!;}w9nPjoz0))m^!X%wyygqwF17)jf1ApzL zPd~iJ6vxvL-oXHV{++jBY=&>3<5^p?apxOeAjb;Px`v?T2VVY4N{P4DizNukVRVdc zQ8Nb-aP5j$MOPk>AH8|c*uv}jC;kSy7B4+akRo5`j+&M)-4bz6F1zW`3nh}iI_|!; zp~Z90cK#CCJdjWjD@@{mPdhi5KepX3kW%%9NOTghV3Q*6-&)*lG}Q={Wd33^u*;MB z1FZ&>S{v1N?u@CA^*)80%@DU}^GM$l=zq_~q(k@1))#3EeP;nsNpUrhg%v<+Iy_I# zxjOqHMyIl#ljK8KPjAe^FniFM(@E}qWst|_>dWrWtCwCv*KM3!qK?0QUY84geE*93 z?7TD*B}+DcahZ0xshZfCR#$q3qAZfxX$pFJb#H%2{>M7`8v_I7g)nmA-gKn?j35)m zO+QQ``2L{2TI$e%ENxpFr*7jgVVtz1Z-i_9kw@GjEmtA9Wq>q9y8*vbdcGhAnGt{{ z-n<)9A`u$6htuRRSrYtlAaCHgvgM`K+`s1l=PrK=7z7vk{S#Np=R0iS>UvJfZjFH` zaJ|l+q@7G$)(H@W_GkdWX~W(BF=HlLBa;TfQLyJm7G}w%t3LSw<%PxCT102Q9bDz} z1L*qb5-sJ#)SA$A>6Y^W$kDD%zAN*q!<1}^(?>2EB)7kCOsW->|CU+0hrUGoRh$-1 zb=--O2zVRlD}TxzPD)e{YJ!Scq=iWz&ZDk_a5qreu_za=aa@Qi8z9<`KjsHEIH6V{>65Qx4x%TfxO|kh|76~|r35W_ zl$#yvHv1QFca>!FvKX$X=Q(2#XWi#tM)!?8S%*J=zuR<3F*iRS%Ul}Hvv7f@(JiqX zsz(Ii<42K44ZX(+pV1?s6M6#Zfie>D9sSL@q~sOtX-(7==p?CF+0l8tGl%dFz%T%3 zE`-2rUxC@5i_D{U!%DHd{E=MRg z*RcsQi?K!2n+Xx)GkBhece)Xe+nnbYX|o9QcpRb9bTFq|8e><8MnNTx?KYAHf)I_^`d)XyqAQRb=^ohDmWzT zl6oAgYTFR@SYJQkO=iULksy61<`TqJyBmd>3-LL2V>OL*t#qqghezSx(?xP{g zTS?^umeGax6|sYY;z-IbytKzLB@mG5 zqc*PfC&PX0>N&(eHeD%YqaXztdwdy9=`Xd-oU~l!m>ZoQzjff4dLP(&6=5a64-0-j z_75Q0ee#fwAPLk8zDZjJorIWq) z+)F{D5ct#!j-}1k1NoTy%+14W6~uOG31?7q;G=ywT^;r$5a;oh>LK8y^SAk@r;YsD z#5SAy0)ko~cN`p7Zz;SaX{)t z{~|%)&+SAw!%C;$Wn-Dg`DXe8r%|v4yEFW&Fh7yzM8=B>FOI4UHjtfJ>S@So%ymm~ z2EMV~-7Y)3mE&HrN^abSRFnqLU%M~5Z?h)=*R{NrANd?u_Rn#B{)I&hlgPPb-DlTN zrf0Ws^s>T+FVdcuoCL8(xuA>xJMR<-6&C+RZmM9-?ywQ9;a;9={Bhra*cHB)bh&2D zFvWybU)i$JNvG68F)`%(2E3!cQNox6!E*1ct2{NQL!mu~0`=+R#U4g1olAFWM3cSf z+n+j4Ji!z@=W`aaEBt%EjrH6`U?d?IT{vwozq(&&Ub(|?9cQBSxrvz4&3(L;pCYtK zAnCg76Vn>bfez;1Z{0uQN&Szu%S1bOWsSyBctjIb%szs(E$H)TTO5Cr6oKK}s8X(n z8l0Gi?8@i4GjSH>ClD56Phk1Igh6oX7Gk;ODgG5Q9Rg{wS(XVZjrxo7qPO{3pab?{ z%slB~^w|YTswv}>ANMQ|<)@$BzC*%EmWT=7_`kMB%YF*EO3VmYs5o!MZr9r<2v#DF zeYJy@N=o53%l#Nv{L%LhH+4v&D0f8d?WM|3)3V}y4pprfYILX;T&InUODW%*jMcke zvMxJCq(1=~olJ?UiP0CkMJw&j?nRK+o)&BkQa-ZWQ`3py2jA!pGBuQEZ-0ZDiw4RV zud;iWsQZQ2-3=Tzd@gD-HhkvAHt68^_Ju?+@Xsn#p}w5=O4QfyvMScQ>po;6fMy|l z63~%NOy@Kl^5j&QFPD8{)rm}vZg`Vu!;ei-dp|E=PUYh_|MfC;CXtPo{UkfPL{05o z8IMr~_d!tL5H04Q*ZZ0AmrGkLy1$vGVJdy3{#OYzSI02oqb9_=;t{jpa5e1N@ZM|V!l26;Z}N*V zdD|O#{szd~cb^O`%k0Ao?7EFKo2~zN0D&y!)ugrT48dWaouN>0BW4V|&2;1m<@CC; zyyAAyeExbcfO2_4(}*-sEKHA4h|^3!a@;l^F z3ajr=^+UGUGN3Zf7`wTaIM{xO16&WwTASeDt1%i-aO9qK{c%f*jWIW)Vg1>N((XaO zyx*4hxKg%B0al@hXid!=;&1;v>T6TWwr9!faA|95RKIGZ%= zGt0`)uW#A8ah9#~rV40YJ`>K=zh3mMRVU|9<%Ybce=E7@Z#0fxWwiWVw^fY_e%J12KS0LhEzQz7oD#hwdRKw6W>>w7&*-%Bria3K9wK{%nsexvu z`o222VzDxeqq9Hv`2C>l!-SQ=(cxC8kb1P<{9xqfXD;pP*7bzB-)u0vYWX>00!T1M zG_TqR+0?mGGrb(^#R$~ef3j5U4fKDG^o^K$MQh<4hEQ0Iv`#TfVcKf3i;&?8!12rN zQhEWRRv4@?zl+FFHG)b(x505{p`^X?$MywJP?Wk5R&?vmL25Toze#pBlD?K)m(re0 zCVvu(a(L!fhA4<)w^pJd7w7C{EsHLP_LmV zSxK}Rw;~~sEvMf(Gzrw6A*4LXdVOJSX!6zCSu&DJ%hS}c4!QnSb4uE3e#9`Y-;aMT zF|vI3bV0g!5y{ZWM71fX}#bdUE%{h%(gyh zk_t}f{DeA$6yrW$g!Dp)VMlv_B9!OWJDw8WUVi@xkf2%}w`Llw%QV;3+YaMaD+J1> zE(dION`N>^Jo2f`@sG0%R`-wJfcaEJTXx7Uxwxp`Pvgg?`jdS**k86=uc`a<Ds+c3W1>!4Bhi1p<~wIHgRy5Jjx+DWs>0}3 zisj@NH9ci8L|tZjS2yx{3>~<2w?p-~C6(T?6G8BkN2^P+J|~;jZDMh)@Al30eyAlY zTR*QCCMd0MiHZAovl%W#V_sLYF}E-aCA}#N6Ivr?gJ(Mr#Tk*(SNtP&0hVVv%Wu zFd1?$%&6IvBoH?%c?H25Utw-mNz~d0)+nc_N9h zhBcv3@8Jj%%)YqhnAcrM7g@Su%GzF8VGTH8=LGvahT}fldQBaPSu~L#$==Y4qFo52 zUF*tOf7CHa)~?M;ne($;%@L(hlbaQdPtSDKII^3bh(^NLvl?h1p+7gk`j=^<{9CV{ zHJ}sq`FOgtmr&UCCB>C7@ACOz#Xmqt0+ADb^>$MPV8AL_i9jAEizUG!2~^hJLdL{= zqJM|98PwUI5GyNT(FEiDQIqEf${;grc)q)6LZ1!2J@#|DuL&@JV}9G!_*iH2xL-4f zvRALr3A5_PgF2)-C&ZR`Eh8-}Ek z4!qxrz#V>Zssh*jqGf#jEMqpea6VF8zI9%0bgb=aW~2+<+K!bB|@O*Cn3{Wr9_=_lZ&Tp>xZ+FbztNex;bjo&uhSC+&T-)dOujx|J3` zS!HVyt~k1h@~PDi)1d1`iZ5?a1^=n|-mKX2sTV+38nT+Bkn~*$68DH)m@_Baz5H|P zWnILOdCse70=jmyY?n|B9_<=B@JE796x-%0WFTfN2T2HA$9Z*=+zgh0^I zL@oA|GEpm}m?ybuf!DlNMw!rfC#I+huiD-4$Y?YgUpfd5;6rhF=**4kHU1HG!7wfT zIW_E}c(Kx8B4GW@7lZL&OAWwDZA$?w4s8zBLL9{ex_3(7DpQ2YQ6i~u{GCCkh7E%d z&^Ar#x90Q+VS?{y#`ys%IwvKyh1=Y18DS`9%vw>_AikKyG!j%?(Ku`A=<&+|hPK1f zoKVWPqz#GqGy$b1rTLMREoOOwF-7gP;&^%E(O(h2aLw3O=A@+|q&#p@l3;ar>57{q z6Kk+)wqTqflqsJ1D}kg;Rq%G?MO?obT2&l^eml<4B}aA7v3_Cca99PXD^GaCZ2-sV zd$t2@LBz>>RO4EGi=e0Tk<#LnBCA%3cs(G@Ea0T6G&P7I$}lv_KBYIgS12sXj`3xX zF+nmpDlWS>c{Q!Hi%)E?>wWUZB!G(SA8lNk%15<28U zlsj@IJ;V0~ET5!1Y{^_F!5X)#mhtY&M2`NP7y~$;2UB+7gzY8}z*NyPk@UluWcdzN zRq9359{U0lty13r=kGYEiv z;>7O(lQ$MVJ}oS1?#StDAaxvsSTK=qTDok~DP7tR-=l?!RuXYs>|tYRvr8pbjOLPlqEXTa#glhaK$xs-e2B1xry z!LXiWJw)hoRX6*&FQ1kj-|XM~bX|%^hWYZ;D@{WBx9$<1@VL?Lid?rD|5-;~vvq>_ zXjk__g}mz@RU`Llf|ilL`XVUFP0dq}YoB6QodNuN5kGgCaMA;)lE)b0bxQsYv~6O)d+i{(%7{9I7z*uX+9( z6LpJ1;nJX+UK&1r(ML(I%>E?}kuSfnuj&Az0V^f%1 zYv4*izmb7mX{;%JhN6PS*OM|80I(b349Wi7utS&y0PzoV6TpSmY&U4tu;hnPx`R9X znUa1ms#Pq{9v$?}wR-kbwNb?h;hW{@o8jXc-|+MOMa{t%Mcq++hw`_?OiNCayeXJz zC(_+8G;N_1S8=WjhKS{Q_s|9=*NHbS-Q$k1_^O>isw4Z|Tkwz@$th!H;IKX-rJN44 zZ;|Ye5fT*_b(a5rCJFP#P9HDsuu@~G_?&viVv>`?7Fl)r;IWtm$$UB@xRoc{F@_xj z-0FBZ`M3*Y`2;jX$@diYaM@)lvDF_lq82DzVWKMdrukXs%gmsN8gHe|m+ITi5Gng* ziy62htqvAyXJUUCllVc^l%J1NRB&v|X)(IXgE$ZQQgSiI8g<2U z=BP@FsW`F5Y*pZBju-OjIPT^`*);9!N-f%Xn1ln(WX29vSEKH9DS99oC@XE8>(}`_ z=Gf6w!8*NzsyB`*ydZ90omwvBuZk(X)15&3H4;FH;e{&yc2QPa~x9H_8HKo+KH%4;Hz$^eyBPn@4qiJVxr z`=Oq)OWXl$yC85~%CufXuQErnqs_DgX4@QP+lSjuQZ!(m%H)YsJnALuC1ddX4k`a(VjL6G}Ir!1u(B1SV>*{zg$&ZZCOr zF=>VYdvOG0_DQv|KL=j2yvm@zq3rLi1mKVv`L!eTSIgfKqe65-LH?sAM2zH{eP*}R}HS?y`N5+5&x5v#6@*Ti8flzE;^nVi=hJQ){e7}=Q= zRh_{lmR_1;t{}zxGU$h`L&9Q7w zvSLDfOM1i``K++vn*c-TU+O8Aiyu28OyAf%cRl}qH}`*u+{LmNv{QR1$3$A8$!ohB OK}lX+u13Zp{Qm*> Date: Wed, 3 Jun 2020 17:31:08 -0700 Subject: [PATCH 362/739] Use helm v3 in acceptance tests --- .circleci/config.yml | 3 ++- test/acceptance/_helpers.bash | 4 ++-- test/docker/Test.dockerfile | 6 +++--- test/terraform/main.tf | 24 ++++-------------------- test/terraform/service-account.yaml | 18 ------------------ test/terraform/variables.tf | 4 ++-- 6 files changed, 13 insertions(+), 46 deletions(-) delete mode 100644 test/terraform/service-account.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index 3e1aa44609..efb3e4c025 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,8 @@ jobs: acceptance: docker: # This image is build from test/docker/Test.dockerfile - - image: hashicorpdev/consul-helm-test:0.3.0 + # version 0.4.0 uses helm v3 as default + - image: hashicorpdev/consul-helm-test:0.4.0 steps: - checkout diff --git a/test/acceptance/_helpers.bash b/test/acceptance/_helpers.bash index a204f6bcf3..6888c5eae4 100644 --- a/test/acceptance/_helpers.bash +++ b/test/acceptance/_helpers.bash @@ -14,14 +14,14 @@ helm_install() { fi helm install -f ${values} \ - --name consul \ + consul \ --wait \ ${BATS_TEST_DIRNAME}/../.. } # helm_delete deletes the Consul chart and all resources. helm_delete() { - helm delete --purge consul + helm delete consul kubectl delete --all pvc } diff --git a/test/docker/Test.dockerfile b/test/docker/Test.dockerfile index 7e3ec3b716..5d0fe1e6f3 100644 --- a/test/docker/Test.dockerfile +++ b/test/docker/Test.dockerfile @@ -6,11 +6,11 @@ # a script to configure kubectl, potentially install Helm, and run the tests # manually. This image only has the dependencies pre-installed. -FROM alpine:latest +FROM alpine:3.11 WORKDIR /root ENV BATS_VERSION "1.1.0" -ENV TERRAFORM_VERSION "0.12.10" +ENV TERRAFORM_VERSION "0.12.26" # base packages RUN apk update && apk add --no-cache --virtual .build-deps \ @@ -43,7 +43,7 @@ RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s mv ./kubectl /usr/local/bin/kubectl # helm -RUN curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash +RUN curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash # bats RUN curl -sSL https://github.com/bats-core/bats-core/archive/v${BATS_VERSION}.tar.gz -o /tmp/bats.tgz \ diff --git a/test/terraform/main.tf b/test/terraform/main.tf index 8204d81a9a..67da3ec711 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -42,30 +42,14 @@ resource "null_resource" "kubectl" { # want this to continue on failure. Generally, this works just fine since # it only operates on local data. provisioner "local-exec" { - when = "destroy" - on_failure = "continue" + when = destroy + on_failure = continue command = "kubectl config get-clusters | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-cluster" } provisioner "local-exec" { - when = "destroy" - on_failure = "continue" + when = destroy + on_failure = continue command = "kubectl config get-contexts | grep ${google_container_cluster.cluster.name} | xargs -n1 kubectl config delete-context" } } - -resource "null_resource" "helm" { - count = var.init_cli ? 1 : 0 - depends_on = ["null_resource.kubectl"] - - triggers = { - cluster = google_container_cluster.cluster.id - } - - provisioner "local-exec" { - command = < Date: Fri, 5 Jun 2020 11:29:34 -0700 Subject: [PATCH 363/739] Add component label to all services This enables querying specific services by labels. Without this label, most services in the chart have no distinguishing labels, making it difficult to target specific services with a label selector. This enables better integration with tools like prometheus-operator which use label selectors to determine which endpoints to monitor, as not all services need to be monitored, and some overlap and reference the same pods. --- templates/dns-service.yaml | 1 + templates/server-service.yaml | 1 + templates/ui-service.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index e7bca50735..1d37abc8ac 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -10,6 +10,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + component: dns {{- if .Values.dns.annotations }} annotations: {{ tpl .Values.dns.annotations . | nindent 4 | trim }} diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 0a619cf385..b32e084e95 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -14,6 +14,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + component: server annotations: {{- if .Values.server.service.annotations }} {{ tpl .Values.server.service.annotations . | nindent 4 | trim }} diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index 6f122717e4..0df5776b45 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -10,6 +10,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} + component: ui {{- if .Values.ui.service.annotations }} annotations: {{ tpl .Values.ui.service.annotations . | nindent 4 | trim }} From 7627d3cca60e6290fb3b1b782783eb40416ec20f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 21 May 2020 13:31:05 -0700 Subject: [PATCH 364/739] Set default resources This enables our chart to be deployed into clusters that require resources to be set for each container. This also prevents our pods from being evicted first when Kubernetes runs out of resources because Kubernetes will prefer to evict pods that have no resource settings. To that end we have set defaults for clients and servers because even in first-run tests we observed those pods being evicted, causing confusing issues. We are setting our requests and limits to the same value so we are considered to have a 'Guaranteed' quality of service class. These default settings were chosen based on observation in a running cluster using `kubectl top` and also looking at GKE metrics. We ran a Consul connect workload at 1 req/s. For the helper components, the load we saw is representative of a production cluster because the workload of these components doesn't change, e.g. the lifecycle sidecar. For the core components like clients, servers and mesh gateways, their resource requirements will increase depending on the workload. We have set their resources to more than double what was observed in a base-case installation so that first-run doesn't require an unnecessary amount of resources but also won't run up against any limits. It's expected that for production, users will tune their settings based on their specific use-case and observed load. In our observations, most of the "helper" containers used a maximum of 10 millicores and 12 Mi of memory. We have set these smaller containers and init containers to 50 millicores and 25 Mi of memory to be safe. For the lifecycle sidecar we observed 2m/12Mi. We set this to 10m/25Mi to keep this footprint small. This setting will also be used for connect-injected apps so we can't increase it too much or it will cause apps to have large resource footprints unnecessarily. For components like sync catalog, connect inject and snapshot agent we saw max usage of 44m/14Mi. Since these are long-running components, we set their resources to 50m/50Mi. For Consul clients we saw maximum usage of 10m/15Mi, we have set these to 100m/100Mi. For Consul servers we same maximum usage of 40m/13Mi. We have set these to 100m/100Mi. For mesh gateways with multi-dc federation we observed maximum usage of 15m/13Mi. We have set these to 100m/100Mi. --- CHANGELOG.md | 50 ++++++++++++++ templates/_helpers.tpl | 9 ++- templates/client-daemonset.yaml | 14 ++++ .../client-snapshot-agent-deployment.yaml | 11 ++++ templates/connect-inject-deployment.yaml | 11 ++++ templates/create-federation-secret-job.yaml | 7 ++ templates/enterprise-license-job.yaml | 14 ++++ templates/mesh-gateway-deployment.yaml | 21 ++++++ templates/server-acl-init-cleanup-job.yaml | 7 ++ templates/server-acl-init-job.yaml | 7 ++ templates/sync-catalog-deployment.yaml | 11 ++++ templates/tls-init-cleanup-job.yaml | 7 ++ templates/tls-init-job.yaml | 7 ++ test/unit/client-daemonset.bats | 10 +-- .../client-snapshot-agent-deployment.bats | 27 ++++++++ test/unit/connect-inject-deployment.bats | 27 ++++++++ test/unit/mesh-gateway-deployment.bats | 8 +-- test/unit/server-statefulset.bats | 10 +-- test/unit/sync-catalog-deployment.bats | 27 ++++++++ values.yaml | 65 ++++++++++++++----- 20 files changed, 320 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 193122f9ab..7e15e81bb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,61 @@ ## Unreleased +FEATURES: + +* Resources are now set on all containers. This enables the chart to be deployed + in clusters that have resource quotas set. This also ensures that Consul + server and client pods won't be evicted by Kubernetes when nodes reach their + resource limits. + + Resource settings have been made configurable for sync catalog, connect inject + and client snapshot deployments. + + The default settings were chosen based on a cluster with a small workload. + For production, we recommend monitoring resource usage and modifying the + defaults according to your usage. + BREAKING CHANGES: * Mesh Gateway: `meshGateway.enableHealthChecks` is no longer supported. This config option was to work around an issue where mesh gateways would not listen on their bind ports until a Connect service was registered. This issue was fixed in Consul 1.6.2. ([GH-464](https://github.com/hashicorp/consul-helm/pull/464)) +* Mesh Gateway: The default resource settings have been changed. To keep + the previous settings, you must set `meshGateway.resources` in your own Helm config. ([GH-466](https://github.com/hashicorp/consul-helm/pull/466)) + + Before: + ```yaml + meshGateway: + resources: + requests: + memory: "128Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "500m" + ``` + + After: + ```yaml + meshGateway: + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + ``` + + * Clients and Servers: There are now default resource settings for Consul clients + and servers. Previously, there were no default settings which meant the default + was unlimited. This change was made because Kubernetes will prefer to evict + pods that don't have resource settings and that resulted in the Consul client + and servers being evicted. The default resource settings were chosen based + on a low-usage cluster. If you are running a production cluster, use the + `kubectl top` command to see how much CPU and memory your clients and servers + are using and set the resources accordingly. ([GH-466](https://github.com/hashicorp/consul-helm/pull/466)] + DEPRECATIONS * Setting resources via YAML string is now deprecated. Instead, set directly as YAML. diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 984098f28c..b424359153 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -97,4 +97,11 @@ This template is for an init container. {{- end }} - name: consul-auto-encrypt-ca-cert mountPath: /consul/tls/client/ca -{{- end -}} \ No newline at end of file + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" +{{- end -}} diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 40949ee41a..39bfe7dd49 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -317,6 +317,13 @@ spec: volumeMounts: - name: aclconfig mountPath: /consul/aclconfig + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- if and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt) }} - name: client-tls-init @@ -348,6 +355,13 @@ spec: - name: consul-ca-key mountPath: /consul/tls/ca/key readOnly: true + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} {{- if .Values.client.nodeSelector }} diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index a09a3a8605..0e2a1b378c 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -125,7 +125,11 @@ spec: {{- end }} mountPath: /consul/tls/ca readOnly: true + {{- end }} {{- end }} + {{- with .Values.client.snapshotAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} {{- end }} {{- if (or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} initContainers: @@ -142,6 +146,13 @@ spec: volumeMounts: - name: aclconfig mountPath: /consul/aclconfig + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 0f4227232e..5f4dae6256 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -161,6 +161,10 @@ spec: readOnly: true {{- end }} {{- end }} + {{- with .Values.connectInject.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if (or .Values.connectInject.certs.secretName .Values.global.tls.enabled) }} volumes: {{- if .Values.connectInject.certs.secretName }} @@ -200,6 +204,13 @@ spec: consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-connect-inject-acl-token" \ -k8s-namespace={{ .Release.Namespace }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} diff --git a/templates/create-federation-secret-job.yaml b/templates/create-federation-secret-job.yaml index f513b159a8..fe493edca5 100644 --- a/templates/create-federation-secret-job.yaml +++ b/templates/create-federation-secret-job.yaml @@ -127,4 +127,11 @@ spec: -resource-prefix="{{ template "consul.fullname" . }}" \ -server-ca-cert-file=/consul/tls/ca/tls.crt \ -server-ca-key-file=/consul/tls/server/ca/tls.key + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index bc6b02fc6f..0adf38c53a 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -99,6 +99,13 @@ spec: mountPath: /consul/tls/ca readOnly: true {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} initContainers: - name: ent-license-acl-init @@ -110,6 +117,13 @@ spec: consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-enterprise-license-acl-token" \ -k8s-namespace={{ .Release.Namespace }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} {{- end }} diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index f1dcaeb48d..2832eea2f1 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -90,6 +90,13 @@ spec: volumeMounts: - name: consul-bin mountPath: /consul-bin + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} {{- include "consul.getAutoEncryptClientCA" . | nindent 8 }} {{- end }} @@ -207,6 +214,13 @@ spec: mountPath: /consul/tls/ca readOnly: true {{- end }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" containers: - name: mesh-gateway image: {{ .Values.meshGateway.imageEnvoy | quote }} @@ -342,6 +356,13 @@ spec: {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} - -token-file=/consul/service/acl-token {{- end }} + resources: + requests: + memory: "25Mi" + cpu: "10m" + limits: + memory: "25Mi" + cpu: "10m" {{- if .Values.meshGateway.priorityClassName }} priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} {{- end }} diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index 87f9b45311..c540fad576 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -52,6 +52,13 @@ spec: - delete-completed-job - -k8s-namespace={{ .Release.Namespace }} - {{ template "consul.fullname" . }}-server-acl-init + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 689a5db22c..7f0c2fe305 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -182,6 +182,13 @@ spec: {{- end }} {{- end }} {{- end }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} {{- end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 6b35d66ed6..eda61a176c 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -176,6 +176,10 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 + {{- with .Values.syncCatalog.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} @@ -188,6 +192,13 @@ spec: consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-catalog-sync-acl-token" \ -k8s-namespace={{ .Release.Namespace }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} diff --git a/templates/tls-init-cleanup-job.yaml b/templates/tls-init-cleanup-job.yaml index cc125c5e6b..5e50f50870 100644 --- a/templates/tls-init-cleanup-job.yaml +++ b/templates/tls-init-cleanup-job.yaml @@ -52,5 +52,12 @@ spec: curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-server-cert \ -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index 29c6d8a7cc..bc00f584cb 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -110,5 +110,12 @@ spec: mountPath: /consul/tls/ca/key readOnly: true {{- end }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" {{- end }} {{- end }} diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 9a15311367..5fc75b66e3 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -150,16 +150,16 @@ load _helpers #-------------------------------------------------------------------- # resources -@test "client/DaemonSet: no resources defined by default" { +@test "client/DaemonSet: resources defined by default" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"100m","memory":"100Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] } -@test "client/DaemonSet: resources can be set" { +@test "client/DaemonSet: resources can be overridden" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ @@ -170,7 +170,7 @@ load _helpers } # Test support for the deprecated method of setting a YAML string. -@test "client/DaemonSet: resources can be set with string" { +@test "client/DaemonSet: resources can be overridden with string" { cd `chart_dir` local actual=$(helm template \ -x templates/client-daemonset.yaml \ diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index 730205e41c..3cdd80c51a 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -335,3 +335,30 @@ load _helpers yq '.spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) [ "${actual}" = "" ] } + +#-------------------------------------------------------------------- +# resources + +@test "client/SnapshotAgentDeployment: default resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"50m","memory":"50Mi"},"requests":{"cpu":"50m","memory":"50Mi"}}' ] +} + +@test "client/SnapshotAgentDeployment: can set resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.snapshotAgent.resources.requests.memory=100Mi' \ + --set 'client.snapshotAgent.resources.requests.cpu=100m' \ + --set 'client.snapshotAgent.resources.limits.memory=200Mi' \ + --set 'client.snapshotAgent.resources.limits.cpu=200m' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"200m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] +} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 8112707d67..7c47434f64 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -849,3 +849,30 @@ load _helpers yq '[.spec.template.spec.containers[0].env[].name] | any(contains("HOST_IP"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# resources + +@test "connectInject/Deployment: default resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"50m","memory":"50Mi"},"requests":{"cpu":"50m","memory":"50Mi"}}' ] +} + +@test "connectInject/Deployment: can set resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.resources.requests.memory=100Mi' \ + --set 'connectInject.resources.requests.cpu=100m' \ + --set 'connectInject.resources.limits.memory=200Mi' \ + --set 'connectInject.resources.limits.cpu=200m' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"200m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] +} diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 5eb5f8e906..f124420a31 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -284,10 +284,10 @@ key2: value2' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) - [ $(echo "${actual}" | yq -r '.requests.memory') = "128Mi" ] - [ $(echo "${actual}" | yq -r '.requests.cpu') = "250m" ] - [ $(echo "${actual}" | yq -r '.limits.memory') = "256Mi" ] - [ $(echo "${actual}" | yq -r '.limits.cpu') = "500m" ] + [ $(echo "${actual}" | yq -r '.requests.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.requests.cpu') = "100m" ] + [ $(echo "${actual}" | yq -r '.limits.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.limits.cpu') = "100m" ] } @test "meshGateway/Deployment: resources can be overridden" { diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 39a64f6a2e..d3f3e428ec 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -83,16 +83,16 @@ load _helpers #-------------------------------------------------------------------- # resources -@test "server/StatefulSet: no resources defined by default" { +@test "server/StatefulSet: resources defined by default" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"100m","memory":"100Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] } -@test "server/StatefulSet: resources can be set" { +@test "server/StatefulSet: resources can be overridden" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ @@ -103,7 +103,7 @@ load _helpers } # Test support for the deprecated method of setting a YAML string. -@test "server/StatefulSet: resources can be set with string" { +@test "server/StatefulSet: resources can be overridden with string" { cd `chart_dir` local actual=$(helm template \ -x templates/server-statefulset.yaml \ diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index 79d05fc6ba..d87df61cdc 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -692,3 +692,30 @@ load _helpers yq '.spec.template.spec.containers[0].command | any(contains("-consul-cross-namespace-acl-policy"))' | tee /dev/stderr) [ "${actual}" = "true" ] } + +#-------------------------------------------------------------------- +# resources + +@test "syncCatalog/Deployment: default resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"50m","memory":"50Mi"},"requests":{"cpu":"50m","memory":"50Mi"}}' ] +} + +@test "syncCatalog/Deployment: can set resources" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.resources.requests.memory=100Mi' \ + --set 'syncCatalog.resources.requests.cpu=100m' \ + --set 'syncCatalog.resources.limits.memory=200Mi' \ + --set 'syncCatalog.resources.limits.cpu=200m' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"200m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] +} diff --git a/values.yaml b/values.yaml index 9f3179ed6a..9bcc6e67db 100644 --- a/values.yaml +++ b/values.yaml @@ -251,12 +251,16 @@ server: # via the extraConfig setting. connect: true - # Resource requests, limits, etc. for the server cluster placement. This - # should map directly to the value of the resources field for a PodSpec. - # By default no direct resource request is made. + # Resource settings for Server agents. # NOTE: The use of a YAML string is deprecated. Instead, set directly as a - # YAML map. - resources: null + # YAML map. + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" # updatePartition is used to control a careful rolling update of Consul # servers. This should be done particularly when changing the version @@ -411,12 +415,16 @@ client: # also changes the clients' advertised IP to the hostIP rather than podIP. exposeGossipPorts: false - # Resource requests, limits, etc. for the client cluster placement. This - # should map directly to the value of the resources field for a PodSpec. - # By default no direct resource request is made. + # Resource settings for Client agents. # NOTE: The use of a YAML string is deprecated. Instead, set directly as a - # YAML map. - resources: null + # YAML map. + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" # extraConfig is a raw string of extra configuration to set with the # client. This should be JSON. @@ -512,6 +520,15 @@ client: secretName: null secretKey: null + # Resource settings for snapshot agent pods. + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns @@ -689,6 +706,15 @@ syncCatalog: # beta.kubernetes.io/arch: amd64 nodeSelector: null + # Resource settings for sync catalog pods. + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + # Log verbosity level. One of "trace", "debug", "info", "warn", or "error". logLevel: info @@ -708,6 +734,15 @@ connectInject: # Defaults to global.image. imageConsul: null + # Resource settings for connect inject pods. + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + # The Docker image for envoy to use as the proxy sidecar when performing # Connect injection. If using Consul 1.7+, the envoy version must be 1.13+. # If not set, the image used depends on the consul-k8s version. For @@ -967,14 +1002,14 @@ meshGateway: # Resource settings for mesh gateway pods. # NOTE: The use of a YAML string is deprecated. Instead, set directly as a - # YAML map. + # YAML map. resources: requests: - memory: "128Mi" - cpu: "250m" + memory: "100Mi" + cpu: "100m" limits: - memory: "256Mi" - cpu: "500m" + memory: "100Mi" + cpu: "100m" # By default, we set an anti affinity so that two gateway pods won't be # on the same node. NOTE: Gateways require that Consul client agents are From 62be032fef9004d31c09ce85a9b890308da66f57 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 8 Jun 2020 12:28:57 -0700 Subject: [PATCH 365/739] Add survey link --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 030675d4fb..626c0f5bff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Consul Helm Chart +⭐ **We're looking for feedback on how folks are using Consul on Kubernetes. Please fill out our brief [survey](https://hashicorp.sjc1.qualtrics.com/jfe/form/SV_4MANbw1BUku7YhL)!** ⭐ + This repository contains the official HashiCorp Helm chart for installing and configuring Consul on Kubernetes. This chart supports multiple use cases of Consul on Kubernetes, depending on the values provided. From 828377e65a96af913ce6123f0c4a3b0c1ad3e146 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 9 Jun 2020 11:18:27 -0700 Subject: [PATCH 366/739] Support custom CA cert for snapshot agent (#481) Support custom CA cert for snapshot agent For users running an S3 compatible storage for the snapshot agent with their own CA cert they need a way to include that in the system certs so that the snapshot agent can connect with their URL. --- .../client-snapshot-agent-deployment.yaml | 5 +++++ .../client-snapshot-agent-deployment.bats | 22 +++++++++++++++++++ values.yaml | 9 ++++++++ 3 files changed, 36 insertions(+) diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index 0e2a1b378c..db392e365a 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -99,6 +99,11 @@ spec: - "/bin/sh" - "-ec" - | + {{- if .Values.client.snapshotAgent.caCert }} + cat < /etc/ssl/certs/custom-ca.pem + {{- .Values.client.snapshotAgent.caCert | nindent 14 }} + EOF + {{- end }} exec /bin/consul snapshot agent \ {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} -config-dir=/consul/config \ diff --git a/test/unit/client-snapshot-agent-deployment.bats b/test/unit/client-snapshot-agent-deployment.bats index 3cdd80c51a..07e160c9b5 100644 --- a/test/unit/client-snapshot-agent-deployment.bats +++ b/test/unit/client-snapshot-agent-deployment.bats @@ -362,3 +362,25 @@ load _helpers yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) [ "${actual}" = '{"limits":{"cpu":"200m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] } + +#-------------------------------------------------------------------- +# client.snapshotAgent.caCert + +@test "client/SnapshotAgentDeployment: if caCert is set it is used in command" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + --set 'client.snapshotAgent.enabled=true' \ + --set 'client.snapshotAgent.caCert=-----BEGIN CERTIFICATE----- +MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + + exp='cat < /etc/ssl/certs/custom-ca.pem +-----BEGIN CERTIFICATE----- +MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL +EOF +exec /bin/consul snapshot agent \' + + [ "${actual}" = "${exp}" ] +} diff --git a/values.yaml b/values.yaml index 9bcc6e67db..69d579914a 100644 --- a/values.yaml +++ b/values.yaml @@ -529,6 +529,15 @@ client: memory: "50Mi" cpu: "50m" + # Optional PEM-encoded CA certificate that will be added to the trusted system CAs. + # Useful if using an S3-compatible storage exposing a self-signed certificate. + # Example + # caCert: | + # -----BEGIN CERTIFICATE----- + # MIIC7jCCApSgAwIBAgIRAIq2zQEVexqxvtxP6J0bXAwwCgYIKoZIzj0EAwIwgbkx + # ... + caCert: null + # Configuration for DNS configuration within the Kubernetes cluster. # This creates a service that routes to all agents (client or server) # for serving DNS requests. This DOES NOT automatically configure kube-dns From 02c86037e94c5dcc6d779658d386bb392e0d7566 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Fri, 12 Jun 2020 16:15:40 -0400 Subject: [PATCH 367/739] Update helm test to validate successful installation - In an installation with ACLs enabled, `consul kv` operations returns a 403 error. Replacing this with a members check allows this test to work in multiple installation modes successfully. Closes #258 Signed-off-by: Ashwin Venkatesh --- templates/tests/test-runner.yaml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index bc836606b1..1dee73b279 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -67,10 +67,12 @@ spec: - "/bin/sh" - "-ec" - | - export VALUE="{{ .Release.Name }}" - consul kv delete _consul_helm_test - consul kv put _consul_helm_test $VALUE - [ `consul kv get _consul_helm_test` = "$VALUE" ] - consul kv delete _consul_helm_test + consul members + if [ $(consul members | grep consul-server | wc -l) != $(consul members | grep consul-server | grep alive | wc -l) ] + then + echo "Failed because not all consul servers are available" + exit 1 + fi + restartPolicy: Never {{- end }} From ca95ef6a3eda95d492f19a9b5b56cbf9d9bd1ec0 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Fri, 12 Jun 2020 16:40:00 -0400 Subject: [PATCH 368/739] Update test to invoke consul members just once Signed-off-by: Ashwin Venkatesh --- templates/tests/test-runner.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/tests/test-runner.yaml b/templates/tests/test-runner.yaml index 1dee73b279..b8b078003b 100644 --- a/templates/tests/test-runner.yaml +++ b/templates/tests/test-runner.yaml @@ -67,8 +67,8 @@ spec: - "/bin/sh" - "-ec" - | - consul members - if [ $(consul members | grep consul-server | wc -l) != $(consul members | grep consul-server | grep alive | wc -l) ] + consul members | tee members.txt + if [ $(grep -c consul-server members.txt) != $(grep consul-server members.txt | grep -c alive) ] then echo "Failed because not all consul servers are available" exit 1 From e54f89f9bec69efea1b3be1bdfce4b4c78fa8b90 Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Fri, 12 Jun 2020 16:31:50 -0700 Subject: [PATCH 369/739] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e15e81bb1..0adad8a197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,10 @@ BREAKING CHANGES: `kubectl top` command to see how much CPU and memory your clients and servers are using and set the resources accordingly. ([GH-466](https://github.com/hashicorp/consul-helm/pull/466)] +IMPROVEMENTS: + +* Add component label to the server, DNS, and UI services [[GH-480](https://github.com/hashicorp/consul-helm/pull/480)]. + DEPRECATIONS * Setting resources via YAML string is now deprecated. Instead, set directly as YAML. From 6265ac192855e56106854ef91a1fb8f9f7be469a Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Mon, 15 Jun 2020 15:53:54 -0500 Subject: [PATCH 370/739] add support for client host networking and tests (#496) * add support for client host networking and tests * Update values.yaml Co-authored-by: Iryna Shustava --- templates/client-daemonset.yaml | 4 ++++ templates/client-podsecuritypolicy.yaml | 4 ++++ test/unit/client-daemonset.bats | 21 +++++++++++++++++++++ test/unit/client-podsecuritypolicy.bats | 24 ++++++++++++++++++++++++ values.yaml | 7 +++++++ 5 files changed, 60 insertions(+) diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 39bfe7dd49..0d83fe865f 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -55,6 +55,10 @@ spec: dnsPolicy: {{ .Values.client.dnsPolicy }} {{- end }} + {{- if .Values.client.hostNetwork }} + hostNetwork: {{ .Values.client.hostNetwork }} + {{- end }} + volumes: - name: data {{- if .Values.client.dataDirectoryHostPath }} diff --git a/templates/client-podsecuritypolicy.yaml b/templates/client-podsecuritypolicy.yaml index 9d46a23837..224e12801a 100644 --- a/templates/client-podsecuritypolicy.yaml +++ b/templates/client-podsecuritypolicy.yaml @@ -26,7 +26,11 @@ spec: {{- if .Values.client.dataDirectoryHostPath }} - 'hostPath' {{- end }} + {{- if .Values.client.hostNetwork }} + hostNetwork: {{ .Values.client.hostNetwork }} + {{- else }} hostNetwork: false + {{- end }} hostPorts: {{- if (not (and .Values.global.tls.enabled .Values.global.tls.httpsOnly)) }} # HTTP Port diff --git a/test/unit/client-daemonset.bats b/test/unit/client-daemonset.bats index 5fc75b66e3..7a7c30cca5 100755 --- a/test/unit/client-daemonset.bats +++ b/test/unit/client-daemonset.bats @@ -962,6 +962,27 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# hostNetwork + +@test "client/DaemonSet: hostNetwork not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec.hostNetwork == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "client/DaemonSet: hostNetwork can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-daemonset.yaml \ + --set 'client.hostNetwork=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.hostNetwork == true' | tee /dev/stderr) + [ "${actual}" = "true" ] +} #-------------------------------------------------------------------- # updateStrategy diff --git a/test/unit/client-podsecuritypolicy.bats b/test/unit/client-podsecuritypolicy.bats index 2622a45e42..35435442dd 100644 --- a/test/unit/client-podsecuritypolicy.bats +++ b/test/unit/client-podsecuritypolicy.bats @@ -129,3 +129,27 @@ load _helpers yq -c '.spec.hostPorts' | tee /dev/stderr) [ "${actual}" = '[{"min":8501,"max":8501},{"min":8502,"max":8502}]' ] } + +#-------------------------------------------------------------------- +# client.hostNetwork = true +@test "client/PodSecurityPolicy: enabled with global.enablePodSecurityPolicies=true and hostNetwork=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'client.hostNetwork=true' \ + . | tee /dev/stderr | + yq '.spec.hostNetwork == true' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +# client.hostNetwork = false +@test "client/PodSecurityPolicy: enabled with global.enablePodSecurityPolicies=true and default hostNetwork=false" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/client-podsecuritypolicy.yaml \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq '.spec.hostNetwork == false' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 69d579914a..84d689e7c1 100644 --- a/values.yaml +++ b/values.yaml @@ -489,6 +489,13 @@ client: # dnsPolicy to use. dnsPolicy: null + # hostNetwork defines whether or not we use host networking instead of hostPort in the event + # that a CNI plugin doesnt support hostPort. This has security implications and is not recommended + # as doing so gives the consul client unnecessary access to all network traffic on the host. + # In most cases, pod network and host network are on different networks so this should be + # combined with `dnsPolicy: ClusterFirstWithHostNet` + hostNetwork: false + # updateStrategy for the DaemonSet. # See https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy. # This should be a multi-line string mapping directly to the updateStrategy From 9c34f8fae1e7543ba0d6891b6005d868704ad010 Mon Sep 17 00:00:00 2001 From: David Yu Date: Mon, 15 Jun 2020 16:53:23 -0700 Subject: [PATCH 371/739] Small formatting changes to Usage (#497) * Small formatting changes to Usage Created a numbered list with code indents to make it easier to follow * Update README.md Co-authored-by: Iryna Shustava --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 626c0f5bff..b5e984db4c 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,21 @@ use Consul with Kubernetes, please see the Detailed installation instructions for Consul on Kubernetes are found [here](https://www.consul.io/docs/k8s/installation/overview). -Add the HashiCorp Helm Repository: +1. Add the HashiCorp Helm Repository: + + $ helm repo add hashicorp https://helm.releases.hashicorp.com + "hashicorp" has been added to your repositories + +2. Ensure you have access to the consul chart: - $ helm repo add hashicorp https://helm.releases.hashicorp.com - hashicorp" has been added to your repositories + $ helm search repo hashicorp/consul + NAME CHART VERSION APP VERSION DESCRIPTION + hashicorp/consul 0.20.1 1.7.2 Official HashiCorp Consul Chart -Ensure you have access to the consul chart: +3. Now you're ready to install Consul! To install Consul with the default configuration using Helm 3 run: - $ helm search repo hashicorp/consul - NAME CHART VERSION APP VERSION DESCRIPTION - hashicorp/consul 0.20.1 1.7.2 Official HashiCorp Consul Chart - -Now you're ready to install Consul! To install Consul with the default configuration using Helm 3 run: - - $ helm install consul hashicorp/consul --set global.name=consul - NAME: consul + $ helm install consul hashicorp/consul --set global.name=consul + NAME: consul Please see the many options supported in the `values.yaml` file. These are also fully documented directly on the From 42b80656b57c76d7cc979e667567aff1d00337b2 Mon Sep 17 00:00:00 2001 From: Yong Wen Chua Date: Wed, 17 Jun 2020 07:37:10 +0800 Subject: [PATCH 372/739] Add Affinity and Tolerations to Inject and Sync (#335) --- templates/connect-inject-deployment.yaml | 10 ++++- templates/sync-catalog-deployment.yaml | 10 ++++- test/unit/connect-inject-deployment.bats | 48 +++++++++++++++++++++++ test/unit/sync-catalog-deployment.bats | 49 ++++++++++++++++++++++++ values.yaml | 18 +++++++++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index 5f4dae6256..a37c949eb8 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -219,5 +219,13 @@ spec: {{- if .Values.connectInject.nodeSelector }} nodeSelector: {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} - {{- end }} + {{- end }} + {{- if .Values.connectInject.affinity }} + affinity: + {{ tpl .Values.connectInject.affinity . | indent 8 | trim }} + {{- end }} + {{- if .Values.connectInject.tolerations }} + tolerations: + {{ tpl .Values.connectInject.tolerations . | indent 8 | trim }} + {{- end }} {{- end }} diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index eda61a176c..7ca6fafacd 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -207,5 +207,13 @@ spec: {{- if .Values.syncCatalog.nodeSelector }} nodeSelector: {{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }} - {{- end }} + {{- end }} + {{- if .Values.syncCatalog.affinity }} + affinity: + {{ tpl .Values.syncCatalog.affinity . | indent 8 | trim }} + {{- end }} + {{- if .Values.syncCatalog.tolerations }} + tolerations: + {{ tpl .Values.syncCatalog.tolerations . | indent 8 | trim }} + {{- end }} {{- end }} diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 7c47434f64..76fc30ff5d 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -234,6 +234,30 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# affinity + +@test "connectInject/Deployment: affinity not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.affinity == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: affinity can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.affinity=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .affinity == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # nodeSelector @@ -267,6 +291,30 @@ load _helpers [ "${actual}" = "testing" ] } +#-------------------------------------------------------------------- +# tolerations + +@test "connectInject/Deployment: tolerations not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: tolerations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.tolerations=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .tolerations == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # centralConfig diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index d87df61cdc..e607d4d8cf 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -307,6 +307,30 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# affinity + +@test "syncCatalog/Deployment: affinity not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.affinity == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: affinity can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.affinity=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .affinity == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # nodeSelector @@ -341,6 +365,31 @@ load _helpers } #-------------------------------------------------------------------- +# tolerations + +@test "syncCatalog/Deployment: tolerations not set by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.tolerations == null' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "syncCatalog/Deployment: tolerations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/sync-catalog-deployment.yaml \ + --set 'syncCatalog.enabled=true' \ + --set 'syncCatalog.tolerations=foobar' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .tolerations == "foobar"' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.bootstrapACLs # global.acls.manageSystemACLs @test "syncCatalog/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { diff --git a/values.yaml b/values.yaml index 84d689e7c1..5c12aeff9a 100644 --- a/values.yaml +++ b/values.yaml @@ -722,6 +722,15 @@ syncCatalog: # beta.kubernetes.io/arch: amd64 nodeSelector: null + # Affinity Settings + # This should be a multi-line string matching the affinity object + affinity: null + + # Toleration Settings + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: null + # Resource settings for sync catalog pods. resources: requests: @@ -858,6 +867,15 @@ connectInject: # beta.kubernetes.io/arch: amd64 nodeSelector: null + # Affinity Settings + # This should be a multi-line string matching the affinity object + affinity: null + + # Toleration Settings + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: null + # aclBindingRuleSelector accepts a query that defines which Service Accounts # can authenticate to Consul and receive an ACL token during Connect injection. # The default setting, i.e. serviceaccount.name!=default, prevents the From b3cc7693a779e4df7594bb6c6cd5e85eec05b3ba Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 26 May 2020 13:34:13 -0700 Subject: [PATCH 373/739] Support default sidecar proxy resources --- templates/connect-inject-deployment.yaml | 18 ++++- test/unit/connect-inject-deployment.bats | 86 ++++++++++++++++++++++++ values.yaml | 20 ++++++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index a37c949eb8..aceed19a94 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -119,10 +119,24 @@ spec: {{- end }} {{- if .Values.connectInject.certs.secretName }} -tls-cert-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.certName }} \ - -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} + -tls-key-file=/etc/connect-injector/certs/{{ .Values.connectInject.certs.keyName }} \ {{- else }} -tls-auto=${CONSUL_FULLNAME}-connect-injector-cfg \ - -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc + -tls-auto-hosts=${CONSUL_FULLNAME}-connect-injector-svc,${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE},${CONSUL_FULLNAME}-connect-injector-svc.${NAMESPACE}.svc \ + {{- end }} + {{- $resources := .Values.connectInject.sidecarProxy.resources }} + {{- /* kindIs is used here to differentiate between null and 0 */}} + {{- if not (kindIs "invalid" $resources.limits.memory) }} + -default-sidecar-proxy-memory-limit={{ $resources.limits.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.requests.memory) }} + -default-sidecar-proxy-memory-request={{ $resources.requests.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.limits.cpu) }} + -default-sidecar-proxy-cpu-limit={{ $resources.limits.cpu }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.requests.cpu) }} + -default-sidecar-proxy-cpu-request={{ $resources.requests.cpu }} \ {{- end }} livenessProbe: httpGet: diff --git a/test/unit/connect-inject-deployment.bats b/test/unit/connect-inject-deployment.bats index 76fc30ff5d..fa39bc7e05 100755 --- a/test/unit/connect-inject-deployment.bats +++ b/test/unit/connect-inject-deployment.bats @@ -924,3 +924,89 @@ load _helpers yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) [ "${actual}" = '{"limits":{"cpu":"200m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}' ] } + +#-------------------------------------------------------------------- +# sidecarProxy.resources + +@test "connectInject/Deployment: by default there are no resource settings" { + cd `chart_dir` + local cmd=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-request"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-request"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-limit"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-limit"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "connectInject/Deployment: can set resource settings" { + cd `chart_dir` + local cmd=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.resources.requests.memory=10Mi' \ + --set 'connectInject.sidecarProxy.resources.requests.cpu=100m' \ + --set 'connectInject.sidecarProxy.resources.limits.memory=20Mi' \ + --set 'connectInject.sidecarProxy.resources.limits.cpu=200m' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-request=10Mi"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-request=100m"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-limit=20Mi"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-limit=200m"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: can set resource settings explicitly to 0" { + cd `chart_dir` + local cmd=$(helm template \ + -x templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.resources.requests.memory=0' \ + --set 'connectInject.sidecarProxy.resources.requests.cpu=0' \ + --set 'connectInject.sidecarProxy.resources.limits.memory=0' \ + --set 'connectInject.sidecarProxy.resources.limits.cpu=0' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-request=0"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-request=0"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-memory-limit=0"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-cpu-limit=0"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/values.yaml b/values.yaml index 5c12aeff9a..a53204130a 100644 --- a/values.yaml +++ b/values.yaml @@ -927,6 +927,26 @@ connectInject: proxyDefaults: | {} + sidecarProxy: + # Set default resources for sidecar proxy. If null, that resource won't + # be set. + # These settings can be overridden on a per-pod basis via these annotations: + # - consul.hashicorp.com/sidecar-proxy-cpu-limit + # - consul.hashicorp.com/sidecar-proxy-cpu-request + # - consul.hashicorp.com/sidecar-proxy-memory-limit + # - consul.hashicorp.com/sidecar-proxy-memory-request + resources: + requests: + # Recommended default: 100Mi + memory: null + # Recommended default: 100m + cpu: null + limits: + # Recommended default: 100Mi + memory: null + # Recommended default: 100m + cpu: null + # Mesh Gateways enable Consul Connect to work across Consul datacenters. meshGateway: # If mesh gateways are enabled, a Deployment will be created that runs From fd20c71c8f454575444e194d9cc4a071ec56870b Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Wed, 17 Jun 2020 12:50:35 -0700 Subject: [PATCH 374/739] Bump consul-k8s and consul versions. Bump consul to 1.8.0, consul-k8s to 0.16.0. Remove experimental warning on federation. --- Chart.yaml | 4 ++-- values.yaml | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Chart.yaml b/Chart.yaml index 04e4b6f3c9..399a010bb3 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 name: consul -version: 0.21.0 -appVersion: 1.7.3 +version: 0.22.0 +appVersion: 1.8.0 description: Official HashiCorp Consul Chart home: https://www.consul.io icon: https://raw.githubusercontent.com/hashicorp/consul-helm/master/assets/icon.png diff --git a/values.yaml b/values.yaml index a53204130a..d43246732c 100644 --- a/values.yaml +++ b/values.yaml @@ -30,7 +30,7 @@ global: # image: "consul:1.5.0" # # Consul Enterprise 1.5.0 # image: "hashicorp/consul-enterprise:1.5.0-ent" - image: "consul:1.7.3" + image: "consul:1.8.0" # array of objects containing image pull secret names that will be applied to # each service account. @@ -53,7 +53,7 @@ global: # If using acls.manageSystemACLs then must be >= 0.10.1. # If using connect inject then must be >= 0.10.1. # If using Consul Enterprise namespaces, must be >= 0.12. - imageK8S: "hashicorp/consul-k8s:0.15.0" + imageK8S: "hashicorp/consul-k8s:0.16.0" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running @@ -200,13 +200,12 @@ global: # Settings related to federating with another Consul datacenter. federation: - # Experimental: Currently this is only available in Consul 1.8.0-beta1. - # To use, set global.image: "consul:1.8.0-beta1". # If enabled, this datacenter will be federation-capable. Only federation # through mesh gateways is supported. # Mesh gateways and servers will be configured to allow federation. # Requires global.tls.enabled, meshGateway.enabled and connectInject.enabled # to be true. + # Requires Consul 1.8+. enabled: false # If true, the chart will create a Kubernetes secret that can be imported From 221d1096f59e16c2ff15e1dbe461d3b8b4c32ad4 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig <16315901+adilyse@users.noreply.github.com> Date: Wed, 13 May 2020 16:25:15 -0700 Subject: [PATCH 375/739] Support ingress gateways This creates all of the necessary templates to enable ingress gateways in the Helm chart. By making use of `ingressGateways.defaults` and `ingressGateways.gateways` setting, it's possible to enable multiple ingress gateways. Names must be provided for each and they must be unique. All fields defined in the `ingressGateways.defaults` may be overridden by defining that field on the relevant `ingressGateways.gateways` entry, with the exception of annotations. Annotations will apply both the default annotations and any gateway specific annotations. In an effort to reduce the intrusiveness of the installation, this feature uses a role and a rolebinding rather than clusterrole/binding. Added support for creating ingress gateway tokens to the server acl init job. Added additional (unrendered) spaces in this job's command to make it easier to reason about. Note: the current default affinity for ingress gateways won't allow more than one ingress gateway to be scheduled on the same node, even if they are logically different gateways. Due to limitations in templating, there's no good way to change this automatically. To work around it, an `ingress-gateway-name` label has been added to the deployment. With it, users will be able to define an affinity per gateway if they would like to allow multiple, but different, gateways per node. --- templates/ingress-gateways-deployment.yaml | 411 ++++++ .../ingress-gateways-podsecuritypolicy.yaml | 44 + templates/ingress-gateways-role.yaml | 46 + templates/ingress-gateways-rolebinding.yaml | 25 + templates/ingress-gateways-service.yaml | 51 + .../ingress-gateways-serviceaccount.yaml | 24 + templates/server-acl-init-job.yaml | 37 +- test/unit/helpers.bats | 4 +- test/unit/ingress-gateways-deployment.bats | 1138 +++++++++++++++++ .../ingress-gateways-podsecuritypolicy.bats | 52 + test/unit/ingress-gateways-role.bats | 105 ++ test/unit/ingress-gateways-rolebinding.bats | 44 + test/unit/ingress-gateways-service.bats | 363 ++++++ .../unit/ingress-gateways-serviceaccount.bats | 70 + test/unit/mesh-gateway-clusterrole.bats | 7 +- .../unit/mesh-gateway-clusterrolebinding.bats | 4 +- test/unit/mesh-gateway-deployment.bats | 36 +- test/unit/mesh-gateway-podsecuritypolicy.bats | 3 +- test/unit/mesh-gateway-service.bats | 15 +- test/unit/mesh-gateway-serviceaccount.bats | 3 +- test/unit/server-acl-init-job.bats | 121 +- test/unit/server-configmap.bats | 4 - values.yaml | 105 ++ 23 files changed, 2642 insertions(+), 70 deletions(-) create mode 100644 templates/ingress-gateways-deployment.yaml create mode 100644 templates/ingress-gateways-podsecuritypolicy.yaml create mode 100644 templates/ingress-gateways-role.yaml create mode 100644 templates/ingress-gateways-rolebinding.yaml create mode 100644 templates/ingress-gateways-service.yaml create mode 100644 templates/ingress-gateways-serviceaccount.yaml create mode 100644 test/unit/ingress-gateways-deployment.bats create mode 100644 test/unit/ingress-gateways-podsecuritypolicy.bats create mode 100644 test/unit/ingress-gateways-role.bats create mode 100644 test/unit/ingress-gateways-rolebinding.bats create mode 100644 test/unit/ingress-gateways-service.bats create mode 100644 test/unit/ingress-gateways-serviceaccount.bats diff --git a/templates/ingress-gateways-deployment.yaml b/templates/ingress-gateways-deployment.yaml new file mode 100644 index 0000000000..d7e3f80185 --- /dev/null +++ b/templates/ingress-gateways-deployment.yaml @@ -0,0 +1,411 @@ +{{- if .Values.ingressGateways.enabled }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} +{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} +{{- $names := dict }} + +{{- range .Values.ingressGateways.gateways }} + +{{- $service := .service }} + +{{- if empty .name }} +# Check that the gateway name is provided +{{ fail "Ingress gateway names cannot be empty"}} +{{ end -}} +{{- if hasKey $names .name }} +# Check that the gateway name is unique +{{ fail "Ingress gateway names must be unique"}} +{{ end -}} +{{- /* Add the gateway name to the $names dict to ensure uniqueness */ -}} +{{- $_ := set $names .name .name }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + replicas: {{ default $defaults.replicas .replicas }} + selector: + matchLabels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + template: + metadata: + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + {{- if $defaults.annotations }} + # We allow both default annotations and gateway-specific annotations + {{- tpl $defaults.annotations $root | nindent 8 }} + {{- end }} + {{- if .annotations }} + {{- tpl .annotations $root | nindent 8 }} + {{- end }} + spec: + {{- if (or $defaults.affinity .affinity) }} + affinity: + {{ tpl (default $defaults.affinity .affinity) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.tolerations .tolerations) }} + tolerations: + {{ tpl (default $defaults.tolerations .tolerations) $root | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} + volumes: + - name: consul-bin + emptyDir: {} + - name: consul-service + emptyDir: + medium: "Memory" + {{- if $root.Values.global.tls.enabled }} + {{- if not (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + secret: + {{- if $root.Values.global.tls.caCert.secretName }} + secretName: {{ $root.Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" $root }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" $root.Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} + initContainers: + # We use the Envoy image as our base image so we use an init container to + # copy the Consul binary to a shared directory that can be used when + # starting Envoy. + - name: copy-consul-bin + image: {{ $root.Values.global.image | quote }} + command: + - cp + - /bin/consul + - /consul-bin/consul + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + {{- if (and $root.Values.global.tls.enabled $root.Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" $root | nindent 8 }} + {{- end }} + # service-init registers the ingress gateway service. + - name: service-init + image: {{ $root.Values.global.imageK8S }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + consul-k8s acl-init \ + -secret-name="{{ template "consul.fullname" $root }}-{{ .name }}-ingress-gateway-acl-token" \ + -k8s-namespace={{ $root.Release.Namespace }} \ + -token-sink-file=/consul/service/acl-token + {{ end }} + + {{- $serviceType := (default $defaults.service.type $service.type) }} + {{- if (eq $serviceType "NodePort") }} + WAN_ADDR="${HOST_IP}" + {{- else if (or (eq $serviceType "ClusterIP") (eq $serviceType "LoadBalancer")) }} + consul-k8s service-address \ + -k8s-namespace={{ $root.Release.Namespace }} \ + -name={{ template "consul.fullname" $root }}-{{ .name }} \ + -resolve-hostnames \ + -output-file=/tmp/address.txt + WAN_ADDR="$(cat /tmp/address.txt)" + {{- else }} + {{- fail "currently set ingressGateway value service.type is not supported" }} + {{- end }} + + {{- if (eq $serviceType "NodePort") }} + {{- if $service.ports }} + {{- $firstPort := first $service.ports}} + {{- if $firstPort.nodePort }} + WAN_PORT={{ $firstPort.nodePort }} + {{- else }}{{ fail "if ingressGateways .service.type=NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a nodePort" }} + {{- end }} + {{- else if $defaults.service.ports }} + {{- $firstDefaultPort := first $defaults.service.ports}} + {{- if $firstDefaultPort.nodePort }} + WAN_PORT={{ $firstDefaultPort.nodePort }} + {{- else }}{{ fail "if ingressGateways .service.type=NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a nodePort" }} + {{- end }} + {{- else }}{{ fail "if ingressGateways .service.type=NodePort, the first port entry in either the defaults or specific gateway must include a nodePort" }} + {{- end }} + + {{- else }} + {{- if $service.ports }} + {{- $firstPort := first $service.ports}} + {{- if $firstPort.port }} + WAN_PORT={{ $firstPort.port }} + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a port" }} + {{- end }} + {{- else if $defaults.service.ports }} + {{- $firstDefaultPort := first $defaults.service.ports}} + {{- if $firstDefaultPort.port }} + WAN_PORT={{ $firstDefaultPort.port }} + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a port" }} + {{- end }} + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort, the first port entry in either the defaults or specific gateway must include a port" }} + {{- end }} + {{- end }} + + cat > /consul/service/service.hcl << EOF + service { + kind = "ingress-gateway" + name = "{{ .name }}" + id = "${POD_NAME}" + {{- if $root.Values.global.enableConsulNamespaces }} + namespace = "{{ (default $defaults.consulNamespace .consulNamespace) }}" + {{- end }} + port = ${WAN_PORT} + address = "${WAN_ADDR}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 21000 + } + wan { + address = "${WAN_ADDR}" + port = ${WAN_PORT} + } + } + proxy { + config { + envoy_gateway_no_default_bind = true + envoy_gateway_bind_addresses { + all-interfaces { + address = "0.0.0.0" + } + } + } + } + checks = [ + { + name = "Ingress Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:21000" + deregister_critical_service_after = "6h" + } + ] + } + EOF + + /consul-bin/consul services register \ + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + -token-file=/consul/service/acl-token \ + {{- end }} + /consul/service/service.hcl + volumeMounts: + - name: consul-service + mountPath: /consul/service + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + containers: + - name: ingress-gateway + image: {{ $root.Values.global.imageEnvoy | quote }} + {{- if (default $defaults.resources .resources) }} + resources: + {{ toYaml (default $defaults.resources .resources) | nindent 12 }} + {{- end }} + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ template "consul.fullname" $root }}-{{ .name }}-ingress-gateway-acl-token" + key: "token" + {{- end}} + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_GRPC_ADDR + value: https://$(HOST_IP):8502 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + - name: CONSUL_GRPC_ADDR + value: $(HOST_IP):8502 + {{- end }} + command: + - /consul-bin/consul + - connect + - envoy + - -gateway=ingress + - -proxy-id=$(POD_NAME) + - -address=$(POD_IP):21000 + {{- if $root.Values.global.enableConsulNamespaces }} + - -namespace={{ default $defaults.consulNamespace .consulNamespace }} + {{- end }} + livenessProbe: + tcpSocket: + port: 21000 + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 21000 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - name: gateway-health + containerPort: 21000 + {{- range $index, $allPorts := (default $defaults.service.ports $service.ports) }} + - name: gateway-{{ $index }} + containerPort: {{ $allPorts.port }} + {{- end }} + lifecycle: + preStop: + exec: + command: + - "/bin/sh" + - "-ec" + - | + /consul-bin/consul services deregister \ + {{- if $root.Values.global.enableConsulNamespaces }} + -namespace={{ default $defaults.consulNamespace .consulNamespace }} \ + {{- end }} + -id="${POD_NAME}" + + # lifecycle-sidecar ensures the ingress gateway is always registered with + # the local Consul agent, even if it loses the initial registration. + - name: lifecycle-sidecar + image: {{ $root.Values.global.imageK8S }} + volumeMounts: + - name: consul-service + mountPath: /consul/service + readOnly: true + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + command: + - consul-k8s + - lifecycle-sidecar + - -service-config=/consul/service/service.hcl + - -consul-binary=/consul-bin/consul + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - -token-file=/consul/service/acl-token + {{- end }} + {{- if (default $defaults.priorityClassName .priorityClassName) }} + priorityClassName: {{ default $defaults.priorityClassName .priorityClassName | quote }} + {{- end }} + {{- if (default $defaults.nodeSelector .nodeSelector) }} + nodeSelector: + {{ tpl (default $defaults.nodeSelector .nodeSelector) $root | indent 8 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/ingress-gateways-podsecuritypolicy.yaml b/templates/ingress-gateways-podsecuritypolicy.yaml new file mode 100644 index 0000000000..f6e8773d8c --- /dev/null +++ b/templates/ingress-gateways-podsecuritypolicy.yaml @@ -0,0 +1,44 @@ +{{- if (and .Values.global.enablePodSecurityPolicies .Values.ingressGateways.enabled) }} +{{- $root := . }} +{{- range .Values.ingressGateways.gateways }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +--- +{{- end }} +{{- end }} diff --git a/templates/ingress-gateways-role.yaml b/templates/ingress-gateways-role.yaml new file mode 100644 index 0000000000..a7e10e2c10 --- /dev/null +++ b/templates/ingress-gateways-role.yaml @@ -0,0 +1,46 @@ +{{- if .Values.ingressGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} + +{{- range .Values.ingressGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +rules: + - apiGroups: [""] + resources: + - services + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - get +{{- if $root.Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - use +{{- end }} +{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }}-ingress-gateway-acl-token + verbs: + - get +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/ingress-gateways-rolebinding.yaml b/templates/ingress-gateways-rolebinding.yaml new file mode 100644 index 0000000000..601de775f4 --- /dev/null +++ b/templates/ingress-gateways-rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.ingressGateways.enabled }} +{{- $root := . }} +{{- range .Values.ingressGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" $root }}-{{ .name }} +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" $root }}-{{ .name }} +--- +{{- end }} +{{- end }} diff --git a/templates/ingress-gateways-service.yaml b/templates/ingress-gateways-service.yaml new file mode 100644 index 0000000000..cf54a740fe --- /dev/null +++ b/templates/ingress-gateways-service.yaml @@ -0,0 +1,51 @@ +{{- if .Values.ingressGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} + +{{- range .Values.ingressGateways.gateways }} + +{{- $service := .service }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if (or $defaults.service.annotations $service.annotations) }} + # We allow both default annotations and gateway-specific annotations + annotations: + {{- if $defaults.service.annotations }} + {{ tpl $defaults.service.annotations $root | nindent 4 | trim }} + {{- end }} + {{- if $service.annotations }} + {{ tpl $service.annotations $root | nindent 4 | trim }} + {{- end }} + {{- end }} +spec: + selector: + app: {{ template "consul.name" $root }} + release: "{{ $root.Release.Name }}" + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + ports: + {{- range $index, $ports := (default $defaults.service.ports $service.ports) }} + - name: gateway-{{ $index }} + port: {{ $ports.port }} + {{- if (and (eq (default $defaults.service.type $service.type) "NodePort") $ports.nodePort) }} + nodePort: {{ $ports.nodePort }} + {{- end}} + {{- end }} + type: {{ default $defaults.service.type $service.type }} + {{- if (default $defaults.service.additionalSpec $service.additionalSpec) }} + {{ tpl (default $defaults.service.additionalSpec $service.additionalSpec) $root | nindent 2 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/ingress-gateways-serviceaccount.yaml b/templates/ingress-gateways-serviceaccount.yaml new file mode 100644 index 0000000000..4be3383d5f --- /dev/null +++ b/templates/ingress-gateways-serviceaccount.yaml @@ -0,0 +1,24 @@ +{{- if .Values.ingressGateways.enabled }} +{{- $root := . }} +{{- range .Values.ingressGateways.gateways }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +{{- with $root.Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 7f0c2fe305..3e2b012908 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -97,6 +97,9 @@ spec: CONSUL_FULLNAME="{{template "consul.fullname" . }}" consul-k8s server-acl-init \ + -resource-prefix=${CONSUL_FULLNAME} \ + -k8s-namespace={{ .Release.Namespace }} \ + {{- if .Values.externalServers.enabled }} {{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} {{- range .Values.externalServers.hosts }} @@ -108,8 +111,7 @@ spec: -server-address="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc" \ {{- end }} {{- end }} - -resource-prefix=${CONSUL_FULLNAME} \ - -k8s-namespace={{ .Release.Namespace }} \ + {{- if .Values.global.tls.enabled }} -use-https \ {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} @@ -119,43 +121,72 @@ spec: -server-port=8501 \ {{- end }} {{- end }} + {{- if .Values.syncCatalog.enabled }} -create-sync-token=true \ {{- end }} + {{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }} -allow-dns=true \ {{- end }} + {{- if .Values.connectInject.enabled }} -create-inject-auth-method=true \ {{- if and .Values.externalServers.enabled .Values.externalServers.k8sAuthMethodHost }} -inject-auth-method-host={{ .Values.externalServers.k8sAuthMethodHost }} \ {{- end }} {{- end }} + {{- if .Values.meshGateway.enabled }} -create-mesh-gateway-token=true \ {{- end }} + + {{- if .Values.ingressGateways.enabled }} + {{- if .Values.global.enableConsulNamespaces }} + {{- $root := . }} + {{- range .Values.ingressGateways.gateways }} + {{- if (or $root.Values.ingressGateways.defaults.consulNamespace .consulNamespace) }} + -ingress-gateway-name="{{ .name }}.{{ (default $root.Values.ingressGateways.defaults.consulNamespace .consulNamespace) }}" \ + {{- else }} + -ingress-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.ingressGateways.gateways }} + -ingress-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.connectInject.aclBindingRuleSelector }} -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \ {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} -create-enterprise-license-token=true \ {{- end }} + {{- if .Values.client.snapshotAgent.enabled }} -create-snapshot-agent-token=true \ {{- end }} + {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} -create-client-token=false \ {{- end }} + {{- if .Values.global.acls.createReplicationToken }} -create-acl-replication-token=true \ {{- end }} + {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} -bootstrap-token-file=/consul/acl/tokens/bootstrap-token \ {{- else if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} -acl-replication-token-file=/consul/acl/tokens/acl-replication-token \ {{- end }} + {{- if .Values.global.enableConsulNamespaces }} -enable-namespaces=true \ + {{- /* syncCatalog must be enabled to set sync flags */}} {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} @@ -168,6 +199,7 @@ spec: {{- end }} {{- end }} {{- end }} + {{- /* connectInject must be enabled to set inject flags */}} {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -create-inject-namespace-token=true \ @@ -181,6 +213,7 @@ spec: {{- end }} {{- end }} {{- end }} + {{- end }} resources: requests: diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index fe9b2fd1a0..ab49d8f742 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -267,9 +267,9 @@ load _helpers @test "helper/bootstrapACLs: used alongside manageSystemACLs" { cd `chart_dir` - diff=$(diff <(grep -r '\.Values\.global\.bootstrapACLs' templates/*) <(grep -r 'or \.Values\.global\.acls\.manageSystemACLs \.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) + diff=$(diff <(grep -r '\.Values\.global\.bootstrapACLs' templates/*) <(grep -r -e 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) [ "$diff" = "" ] - diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r 'or \.Values\.global\.acls\.manageSystemACLs \.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) + diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) [ "$diff" = "" ] } diff --git a/test/unit/ingress-gateways-deployment.bats b/test/unit/ingress-gateways-deployment.bats new file mode 100644 index 0000000000..d27e16404d --- /dev/null +++ b/test/unit/ingress-gateways-deployment.bats @@ -0,0 +1,1138 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateways/Deployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Deployment: enabled with ingressGateways, connectInject enabled, has default gateway name" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s '.[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-ingress-gateway" ] +} + +#-------------------------------------------------------------------- +# prerequisites + +@test "ingressGateways/Deployment: fails if connectInject.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "connectInject.enabled must be true" ]] +} + +@test "ingressGateways/Deployment: fails if client.grpc=false" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'client.grpc=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "client.grpc must be true" ]] +} + +@test "ingressGateways/Deployment: fails if global.enabled is false and clients are not explicitly enabled" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +@test "ingressGateways/Deployment: fails if global.enabled is true but clients are explicitly disabled" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enabled=true' \ + --set 'client.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +#-------------------------------------------------------------------- +# envoyImage + +@test "ingressGateways/Deployment: envoy image has default global value" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] +} + +@test "ingressGateways/Deployment: envoy image can be set using the global value" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imageEnvoy=new/image' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "new/image" ] +} + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "ingressGateways/Deployment: sets TLS flags when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_GRPC_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8502' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "ingressGateways/Deployment: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/client-snapshot-agent-deployment.yaml \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual=$(echo $ca_cert_volume | yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + local actual=$(echo $ca_cert_volume | yq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "ingressGateways/Deployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +#-------------------------------------------------------------------- +# replicas + +@test "ingressGateways/Deployment: replicas defaults to 2" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "ingressGateways/Deployment: replicas can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.replicas=3' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "3" ] +} + +@test "ingressGateways/Deployment: replicas can be set through specific gateway, overrides default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.replicas=3' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].replicas=12' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "12" ] +} + +#-------------------------------------------------------------------- +# ports + +@test "ingressGateways/Deployment: has default ports" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].containerPort' | tee /dev/stderr) + [ "${actual}" = "21000" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-health" ] + + local actual=$(echo $object | yq -r '.[1].containerPort' | tee /dev/stderr) + [ "${actual}" = "8080" ] + + local actual=$(echo $object | yq -r '.[1].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] + + local actual=$(echo $object | yq -r '.[2].containerPort' | tee /dev/stderr) + [ "${actual}" = "8443" ] + + local actual=$(echo $object | yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "gateway-1" ] +} + +@test "ingressGateways/Deployment: can set ports through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].port=1234' \ + --set 'ingressGateways.defaults.service.ports[1].port=4444' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].containerPort' | tee /dev/stderr) + [ "${actual}" = "21000" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-health" ] + + local actual=$(echo $object | yq -r '.[1].containerPort' | tee /dev/stderr) + [ "${actual}" = "1234" ] + + local actual=$(echo $object | yq -r '.[1].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] + + local actual=$(echo $object | yq -r '.[2].containerPort' | tee /dev/stderr) + [ "${actual}" = "4444" ] + + local actual=$(echo $object | yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "gateway-1" ] +} + +@test "ingressGateways/Deployment: can set ports through specific gateway overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].containerPort' | tee /dev/stderr) + [ "${actual}" = "21000" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-health" ] + + local actual=$(echo $object | yq -r '.[1].containerPort' | tee /dev/stderr) + [ "${actual}" = "1234" ] + + local actual=$(echo $object | yq -r '.[1].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] +} + +#-------------------------------------------------------------------- +# resources + +@test "ingressGateways/Deployment: resources has default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + [ $(echo "${actual}" | yq -r '.requests.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.requests.cpu') = "100m" ] + [ $(echo "${actual}" | yq -r '.limits.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.limits.cpu') = "100m" ] +} + +@test "ingressGateways/Deployment: resources can be set through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.resources.requests.memory=memory' \ + --set 'ingressGateways.defaults.resources.requests.cpu=cpu' \ + --set 'ingressGateways.defaults.resources.limits.memory=memory2' \ + --set 'ingressGateways.defaults.resources.limits.cpu=cpu2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.requests.memory' | tee /dev/stderr) + [ "${actual}" = "memory" ] + + local actual=$(echo $object | yq -r '.requests.cpu' | tee /dev/stderr) + [ "${actual}" = "cpu" ] + + local actual=$(echo $object | yq -r '.limits.memory' | tee /dev/stderr) + [ "${actual}" = "memory2" ] + + local actual=$(echo $object | yq -r '.limits.cpu' | tee /dev/stderr) + [ "${actual}" = "cpu2" ] +} + +@test "ingressGateways/Deployment: resources can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.resources.requests.memory=memory' \ + --set 'ingressGateways.defaults.resources.requests.cpu=cpu' \ + --set 'ingressGateways.defaults.resources.limits.memory=memory2' \ + --set 'ingressGateways.defaults.resources.limits.cpu=cpu2' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].resources.requests.memory=gwmemory' \ + --set 'ingressGateways.gateways[0].resources.requests.cpu=gwcpu' \ + --set 'ingressGateways.gateways[0].resources.limits.memory=gwmemory2' \ + --set 'ingressGateways.gateways[0].resources.limits.cpu=gwcpu2' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.requests.memory' | tee /dev/stderr) + [ "${actual}" = "gwmemory" ] + + local actual=$(echo $object | yq -r '.requests.cpu' | tee /dev/stderr) + [ "${actual}" = "gwcpu" ] + + local actual=$(echo $object | yq -r '.limits.memory' | tee /dev/stderr) + [ "${actual}" = "gwmemory2" ] + + local actual=$(echo $object | yq -r '.limits.cpu' | tee /dev/stderr) + [ "${actual}" = "gwcpu2" ] +} + +#-------------------------------------------------------------------- +# affinity + +@test "ingressGateways/Deployment: affinity defaults to one per node" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey' | tee /dev/stderr) + [ "${actual}" = "kubernetes.io/hostname" ] +} + +@test "ingressGateways/Deployment: affinity can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.affinity=key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "ingressGateways/Deployment: affinity can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.affinity=key: value' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].affinity=key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# tolerations + +@test "ingressGateways/Deployment: no tolerations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Deployment: tolerations can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.tolerations=- key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations[0].key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "ingressGateways/Deployment: tolerations can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.tolerations=- key: value' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].tolerations=- key: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations[0].key' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# nodeSelector + +@test "ingressGateways/Deployment: no nodeSelector by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Deployment: can set a nodeSelector through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.nodeSelector=key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "ingressGateways/Deployment: can set a nodeSelector through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.nodeSelector=key: value' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].nodeSelector=key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# priorityClassName + +@test "ingressGateways/Deployment: no priorityClassName by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Deployment: can set a priorityClassName through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.priorityClassName=name' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "name" ] +} + +@test "ingressGateways/Deployment: can set a priorityClassName per gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.priorityClassName=name' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].priorityClassName=priority' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "priority" ] +} + +#-------------------------------------------------------------------- +# annotations + +@test "ingressGateways/Deployment: no extra annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "ingressGateways/Deployment: extra annotations can be set through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "ingressGateways/Deployment: extra annotations can be set through specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "ingressGateways/Deployment: extra annotations can be set through defaults and specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.annotations=defaultkey: defaultvalue' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "4" ] + + local actual=$(echo $object | yq -r '.defaultkey' | tee /dev/stderr) + [ "${actual}" = "defaultvalue" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# WAN_ADDR + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for ClusterIP service set in defaults (the default)" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"$(cat /tmp/address.txt)\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for ClusterIP service set in specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=Static' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=ClusterIP' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"$(cat /tmp/address.txt)\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for LoadBalancer service set in defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"$(cat /tmp/address.txt)\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for LoadBalancer service set in specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"$(cat /tmp/address.txt)\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for NodePort service set in defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"${HOST_IP}\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR set correctly for NodePort service set in specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=NodePort' \ + --set 'ingressGateways.gateways[0].service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_ADDR=\"${HOST_IP}\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_ADDR definition fails if using unknown service type in defaults" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=Static' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "currently set ingressGateway value service.type is not supported" ]] +} + +@test "ingressGateways/Deployment: WAN_ADDR definition fails if using unknown service type in specific gateway overriding defaults" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=Static' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "currently set ingressGateway value service.type is not supported" ]] +} + +#-------------------------------------------------------------------- +# WAN_PORT + +@test "ingressGateways/Deployment: WAN_PORT set correctly for non-NodePort service in defaults (the default)" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_PORT=80")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_PORT can be set for non-NodePort service in defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].port=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_PORT=1234")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_PORT set correctly for non-NodePort service in specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_PORT=1234")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_PORT set correctly for NodePort service with nodePort set in defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_PORT=1234")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_PORT set correctly for NodePort service with nodePort set in specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=8888' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=NodePort' \ + --set 'ingressGateways.gateways[0].service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("WAN_PORT=1234")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: WAN_PORT definition fails if .service.type=NodePort and ports[0].nodePort is empty in defaults" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if ingressGateways .service.type=NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a nodePort" ]] +} + +@test "ingressGateways/Deployment: WAN_PORT definition fails if .service.type=NodePort and ports[0].nodePort is empty in specific gateway and not provided in defaults" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=1234' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if ingressGateways .service.type=NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a nodePort" ]] +} + +@test "ingressGateways/Deployment: WAN_PORT definition fails if .service.type=NodePort and ports[0].nodePort is empty in defaults and specific gateway" { + cd `chart_dir` + run helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports=null' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "if ingressGateways .service.type=NodePort, the first port entry in either the defaults or specific gateway must include a nodePort" ]] +} + +#-------------------------------------------------------------------- +# service-init init container + +@test "ingressGateways/Deployment: service-init init container defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-ingress-gateway \ + -resolve-hostnames \ + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" +WAN_PORT=8080 + +cat > /consul/service/service.hcl << EOF +service { + kind = "ingress-gateway" + name = "ingress-gateway" + id = "${POD_NAME}" + port = ${WAN_PORT} + address = "${WAN_ADDR}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 21000 + } + wan { + address = "${WAN_ADDR}" + port = ${WAN_PORT} + } + } + proxy { + config { + envoy_gateway_no_default_bind = true + envoy_gateway_bind_addresses { + all-interfaces { + address = "0.0.0.0" + } + } + } + } + checks = [ + { + name = "Ingress Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:21000" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "ingressGateways/Deployment: service-init init container with acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s acl-init \ + -secret-name="release-name-consul-ingress-gateway-ingress-gateway-acl-token" \ + -k8s-namespace=default \ + -token-sink-file=/consul/service/acl-token + +consul-k8s service-address \ + -k8s-namespace=default \ + -name=release-name-consul-ingress-gateway \ + -resolve-hostnames \ + -output-file=/tmp/address.txt +WAN_ADDR="$(cat /tmp/address.txt)" +WAN_PORT=8080 + +cat > /consul/service/service.hcl << EOF +service { + kind = "ingress-gateway" + name = "ingress-gateway" + id = "${POD_NAME}" + port = ${WAN_PORT} + address = "${WAN_ADDR}" + tagged_addresses { + lan { + address = "${POD_IP}" + port = 21000 + } + wan { + address = "${WAN_ADDR}" + port = ${WAN_PORT} + } + } + proxy { + config { + envoy_gateway_no_default_bind = true + envoy_gateway_bind_addresses { + all-interfaces { + address = "0.0.0.0" + } + } + } + } + checks = [ + { + name = "Ingress Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:21000" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + -token-file=/consul/service/acl-token \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "ingressGateways/Deployment: service-init init container includes service-address command for LoadBalancer set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("consul-k8s service-address")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: service-init init container includes service-address command for LoadBalancer set through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("consul-k8s service-address")' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: service-init init container does not include service-address command for NodePort set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports[0].port=80' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("consul-k8s service-address")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Deployment: service-init init container does not include service-address command for NodePort set through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].service.type=NodePort' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=80' \ + --set 'ingressGateways.gateways[0].service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2] | contains("consul-k8s service-address")' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# namespaces + +@test "ingressGateways/Deployment: namespace command flag is not present by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Deployment: namespace command flag is specified through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'ingressGateways.defaults.consulNamespace=namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace=namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace=namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: namespace command flag is specified through specific gateway overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'ingressGateways.defaults.consulNamespace=namespace' \ + --set 'ingressGateways.gateways[0].name=ingress-gateway' \ + --set 'ingressGateways.gateways[0].consulNamespace=new-namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace=new-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace=new-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# multiple gateways + +@test "ingressGateways/Deployment: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[0] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[1] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/ingress-gateways-podsecuritypolicy.bats b/test/unit/ingress-gateways-podsecuritypolicy.bats new file mode 100644 index 0000000000..9d782e767f --- /dev/null +++ b/test/unit/ingress-gateways-podsecuritypolicy.bats @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateways/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/PodSecurityPolicy: enabled with ingressGateways, connectInject enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-podsecuritypolicy.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/PodSecurityPolicy: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-podsecuritypolicy.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq '.[0] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[1] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] +} diff --git a/test/unit/ingress-gateways-role.bats b/test/unit/ingress-gateways-role.bats new file mode 100644 index 0000000000..fe7a0f71fd --- /dev/null +++ b/test/unit/ingress-gateways-role.bats @@ -0,0 +1,105 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateways/Role: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Role: enabled with ingressGateways, connectInject enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Role: rules for PodSecurityPolicy" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules[1].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +@test "ingressGateways/Role: rules for global.acls.manageSystemACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules[1]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] + + local actual=$(echo $object | yq -r '.resourceNames[0]' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-ingress-gateway-ingress-gateway-acl-token" ] +} + +@test "ingressGateways/Role: rules for ingressGateways service" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "services" ] +} + +@test "ingressGateways/Role: rules for ACLs, PSPs and ingress gateways" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules | length' | tee /dev/stderr) + [ "${actual}" = "3" ] +} + +@test "ingressGateways/Role: rules for ACLs, PSPs and ingress gateways with multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[0].rules | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq '.[1].rules | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/ingress-gateways-rolebinding.bats b/test/unit/ingress-gateways-rolebinding.bats new file mode 100644 index 0000000000..047bdc14dd --- /dev/null +++ b/test/unit/ingress-gateways-rolebinding.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateway/RoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-rolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateway/RoleBinding: enabled with ingressGateways, connectInject enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-rolebinding.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/RoleBinding: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-role.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/ingress-gateways-service.bats b/test/unit/ingress-gateways-service.bats new file mode 100644 index 0000000000..d49b36bd95 --- /dev/null +++ b/test/unit/ingress-gateways-service.bats @@ -0,0 +1,363 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateways/Service: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Service: enabled by default with ingressGateways, connectInject andenabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s '.[0] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# annotations + +@test "ingressGateways/Service: no annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].metadata.annotations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Deployment: annotations can be set through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "2" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "ingressGateways/Service: annotations can be set through specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "2" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "ingressGateways/Service: annotations can be set through defaults and specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.annotations=defaultkey: defaultvalue' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq -r '.defaultkey' | tee /dev/stderr) + [ "${actual}" = "defaultvalue" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# port + +@test "ingressGateways/Service: has default ports" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].port' | tee /dev/stderr) + [ "${actual}" = "8080" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] + + local actual=$(echo $object | yq -r '.[1].port' | tee /dev/stderr) + [ "${actual}" = "8443" ] + + local actual=$(echo $object | yq -r '.[1].name' | tee /dev/stderr) + [ "${actual}" = "gateway-1" ] +} + +@test "ingressGateways/Service: can set ports through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].port=4443' \ + --set 'ingressGateways.defaults.service.ports[1].port=4444' \ + --set 'ingressGateways.defaults.service.ports[2].port=4445' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].port' | tee /dev/stderr) + [ "${actual}" = "4443" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] + + local actual=$(echo $object | yq -r '.[1].port' | tee /dev/stderr) + [ "${actual}" = "4444" ] + + local actual=$(echo $object | yq -r '.[1].name' | tee /dev/stderr) + [ "${actual}" = "gateway-1" ] + + local actual=$(echo $object | yq -r '.[2].port' | tee /dev/stderr) + [ "${actual}" = "4445" ] + + local actual=$(echo $object | yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "gateway-2" ] +} + +@test "ingressGateways/Service: can set ports through specific gateway overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].port=8443' \ + --set 'ingressGateways.defaults.service.ports[1].port=8444' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].port' | tee /dev/stderr) + [ "${actual}" = "1234" ] + + local actual=$(echo $object | yq -r '.[0].name' | tee /dev/stderr) + [ "${actual}" = "gateway-0" ] + + local actual=$(echo $object | yq '.[1] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/Service: can set port through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.port=8443' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports[0].port' | tee /dev/stderr) + [ "${actual}" = "1234" ] +} + +#-------------------------------------------------------------------- +# nodePort + +@test "ingressGateways/Service: no nodePort by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Service: if not a NodePort service, cannot set a nodePort through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.ports[0].port=80' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=4443' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "ingressGateways/Service: can set a nodePort through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports[0].port=80' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=4443' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "4443" ] +} + +@test "ingressGateways/Service: can set a nodePort through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.defaults.service.ports[0].nodePort=4443' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.ports[0].port=80' \ + --set 'ingressGateways.gateways[0].service.ports[0].nodePort=1234' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.ports[0].nodePort' | tee /dev/stderr) + [ "${actual}" = "1234" ] +} + +#-------------------------------------------------------------------- +# Service type + +@test "ingressGateways/Service: defaults to type ClusterIP" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.type' | tee /dev/stderr) + [ "${actual}" = "ClusterIP" ] +} + +@test "ingressGateways/Service: can set type through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=LoadBalancer' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] +} + +@test "ingressGateways/Service: can set type through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.type=NodePort' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.type=ClusterIP' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.type' | tee /dev/stderr) + [ "${actual}" = "ClusterIP" ] +} + +#-------------------------------------------------------------------- +# additionalSpec + +@test "ingressGateways/Service: can add additionalSpec through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.additionalSpec=key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "ingressGateways/Service: can add additionalSpec through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.defaults.service.additionalSpec=key: value' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[0].service.additionalSpec=key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# selectors + +@test "ingressGateways/Service: label selectors uniquely identify gateways" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.selector."ingress-gateway-name"' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-ingress-gateway" ] +} + +#-------------------------------------------------------------------- +# multiple gateways + +@test "ingressGateways/Service: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-service.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/ingress-gateways-serviceaccount.bats b/test/unit/ingress-gateways-serviceaccount.bats new file mode 100644 index 0000000000..a00d25940f --- /dev/null +++ b/test/unit/ingress-gateways-serviceaccount.bats @@ -0,0 +1,70 @@ +#!/usr/bin/env bats + +load _helpers + +@test "ingressGateways/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "ingressGateways/ServiceAccount: enabled with ingressGateways, connectInject enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-serviceaccount.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "ingressGateways/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-serviceaccount.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -s -r '.[0].imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -s -r '.[0].imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + +#-------------------------------------------------------------------- +# multiple gateways + +@test "ingressGateways/ServiceAccount: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/ingress-gateways-serviceaccount.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo "$object" | + yq -r '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/mesh-gateway-clusterrole.bats b/test/unit/mesh-gateway-clusterrole.bats index 988e22bcd3..621f78e484 100644 --- a/test/unit/mesh-gateway-clusterrole.bats +++ b/test/unit/mesh-gateway-clusterrole.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ClusterRole: enabled with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/ClusterRole: enabled with meshGateway, connectInject enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -29,7 +28,6 @@ load _helpers -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules[0].resources[0]' | tee /dev/stderr) @@ -42,7 +40,6 @@ load _helpers -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq -r '.rules[0].resources[0]' | tee /dev/stderr) @@ -70,7 +67,6 @@ load _helpers --set 'meshGateway.enabled=true' \ --set 'meshGateway.wanAddress.source=NodeIP' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.rules' | tee /dev/stderr) [ "${actual}" = "[]" ] @@ -82,7 +78,6 @@ load _helpers -x templates/mesh-gateway-clusterrole.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ --set 'meshGateway.service.enabled=true' \ diff --git a/test/unit/mesh-gateway-clusterrolebinding.bats b/test/unit/mesh-gateway-clusterrolebinding.bats index 92400bb31f..9042c2ff07 100644 --- a/test/unit/mesh-gateway-clusterrolebinding.bats +++ b/test/unit/mesh-gateway-clusterrolebinding.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ClusterRoleBinding: enabled with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/ClusterRoleBinding: enabled with meshGateway, connectInject enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-clusterrolebinding.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -29,7 +28,6 @@ load _helpers -x templates/mesh-gateway-clusterrolebinding.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --name 'release-name' \ . | tee /dev/stderr | yq -r '.subjects[0].name' | tee /dev/stderr) diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index f124420a31..2a516bb6e2 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/Deployment: enabled with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/Deployment: enabled with meshGateway, connectInject enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -31,8 +30,7 @@ load _helpers run helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ - --set 'connectInject.enabled=false' \ - --set 'client.grpc=true' . + --set 'connectInject.enabled=false' . [ "$status" -eq 1 ] [[ "$output" =~ "connectInject.enabled must be true" ]] } @@ -53,7 +51,6 @@ load _helpers run helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ - --set 'client.grpc=true' \ --set 'connectInject.enabled=true' \ --set 'global.enabled=false' . [ "$status" -eq 1 ] @@ -65,7 +62,6 @@ load _helpers run helm template \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ - --set 'client.grpc=true' \ --set 'connectInject.enabled=true' \ --set 'global.enabled=true' \ --set 'client.enabled=false' . @@ -82,7 +78,6 @@ load _helpers -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.metadata.annotations | length' | tee /dev/stderr) [ "${actual}" = "1" ] @@ -94,7 +89,6 @@ load _helpers -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.annotations=key1: value1 key2: value2' \ . | tee /dev/stderr | @@ -111,7 +105,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.replicas' | tee /dev/stderr) [ "${actual}" = "2" ] @@ -123,7 +116,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.replicas=3' \ . | tee /dev/stderr | yq -r '.spec.replicas' | tee /dev/stderr) @@ -139,7 +131,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey' | tee /dev/stderr) [ "${actual}" = "kubernetes.io/hostname" ] @@ -151,7 +142,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.affinity=key: value' \ . | tee /dev/stderr | yq -r '.spec.template.spec.affinity.key' | tee /dev/stderr) @@ -167,7 +157,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.tolerations' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -179,7 +168,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.tolerations=- key: value' \ . | tee /dev/stderr | yq -r '.spec.template.spec.tolerations[0].key' | tee /dev/stderr) @@ -196,7 +184,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.hostNetwork' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -208,7 +195,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.hostNetwork=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.hostNetwork' | tee /dev/stderr) @@ -224,7 +210,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.dnsPolicy' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -236,7 +221,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.dnsPolicy=ClusterFirst' \ . | tee /dev/stderr | yq -r '.spec.template.spec.dnsPolicy' | tee /dev/stderr) @@ -252,7 +236,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] @@ -264,7 +247,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.imageEnvoy=new/image' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) @@ -280,7 +262,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].resources' | tee /dev/stderr) @@ -296,7 +277,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.resources.foo=bar' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) @@ -326,7 +306,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) @@ -341,7 +320,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.containerPort=9443' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr) @@ -360,7 +338,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.consulServiceName=override' \ --set 'global.acls.manageSystemACLs=true' \ . @@ -374,7 +351,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.consulServiceName=mesh-gateway' \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr \ @@ -389,7 +365,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.consulServiceName=overridden' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) @@ -406,7 +381,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr \ | yq '.spec.template.spec.containers[0]' | tee /dev/stderr ) @@ -425,7 +399,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].ports[0].hostPort' | tee /dev/stderr) @@ -438,7 +411,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.hostPort=443' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].ports[0].hostPort' | tee /dev/stderr) @@ -455,7 +427,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) @@ -468,7 +439,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.priorityClassName=name' \ . | tee /dev/stderr | yq -r '.spec.template.spec.priorityClassName' | tee /dev/stderr) @@ -485,7 +455,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.nodeSelector' | tee /dev/stderr) @@ -498,7 +467,6 @@ key2: value2' \ -x templates/mesh-gateway-deployment.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.nodeSelector=key: value' \ . | tee /dev/stderr | yq -r '.spec.template.spec.nodeSelector.key' | tee /dev/stderr) diff --git a/test/unit/mesh-gateway-podsecuritypolicy.bats b/test/unit/mesh-gateway-podsecuritypolicy.bats index 2fb55cf17c..a27a3fa9ab 100644 --- a/test/unit/mesh-gateway-podsecuritypolicy.bats +++ b/test/unit/mesh-gateway-podsecuritypolicy.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/PodSecurityPolicy: enabled with meshGateway, connectInject and client.grpc enabled and global.enablePodSecurityPolicies=true" { +@test "meshGateway/PodSecurityPolicy: enabled with meshGateway, connectInject enabled and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-podsecuritypolicy.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) diff --git a/test/unit/mesh-gateway-service.bats b/test/unit/mesh-gateway-service.bats index a5f35eeb36..4c65344a2c 100755 --- a/test/unit/mesh-gateway-service.bats +++ b/test/unit/mesh-gateway-service.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/Service: enabled by default with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/Service: enabled by default with meshGateway, connectInject enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] @@ -29,7 +28,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -45,7 +43,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.metadata.annotations' | tee /dev/stderr) @@ -58,7 +55,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.annotations=key: value' \ . | tee /dev/stderr | @@ -75,7 +71,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.ports[0].port' | tee /dev/stderr) @@ -88,7 +83,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.port=8443' \ . | tee /dev/stderr | @@ -105,7 +99,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.ports[0].targetPort' | tee /dev/stderr) @@ -118,7 +111,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.containerPort=9443' \ . | tee /dev/stderr | @@ -135,7 +127,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.ports[0].nodePort' | tee /dev/stderr) @@ -148,7 +139,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.nodePort=8443' \ . | tee /dev/stderr | @@ -165,7 +155,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.type' | tee /dev/stderr) @@ -178,7 +167,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.type=ClusterIP' \ . | tee /dev/stderr | @@ -195,7 +183,6 @@ load _helpers -x templates/mesh-gateway-service.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ --set 'meshGateway.service.enabled=true' \ --set 'meshGateway.service.additionalSpec=key: value' \ . | tee /dev/stderr | diff --git a/test/unit/mesh-gateway-serviceaccount.bats b/test/unit/mesh-gateway-serviceaccount.bats index 9684634502..33680bd520 100644 --- a/test/unit/mesh-gateway-serviceaccount.bats +++ b/test/unit/mesh-gateway-serviceaccount.bats @@ -11,13 +11,12 @@ load _helpers [ "${actual}" = "false" ] } -@test "meshGateway/ServiceAccount: enabled with meshGateway, connectInject and client.grpc enabled" { +@test "meshGateway/ServiceAccount: enabled with meshGateway, connectInject enabled" { cd `chart_dir` local actual=$(helm template \ -x templates/mesh-gateway-serviceaccount.yaml \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 34e987250f..1cc4171400 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -258,6 +258,20 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# meshGateway.enabled + +@test "serverACLInit/Job: mesh gateway acl option disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-create-mesh-gateway-token"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "serverACLInit/Job: mesh gateway acl option enabled with .meshGateway.enabled=true" { cd `chart_dir` local actual=$(helm template \ @@ -265,12 +279,117 @@ load _helpers --set 'global.acls.manageSystemACLs=true' \ --set 'meshGateway.enabled=true' \ --set 'connectInject.enabled=true' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].command | any(contains("-create-mesh-gateway-token"))' | tee /dev/stderr) [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# ingressGateways.enabled + +@test "serverACLInit/Job: ingress gateways acl options disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-ingress-gateway-name"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: ingress gateways acl option enabled with .ingressGateways.enabled=true (single default gateway)" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-ingress-gateway-name=\"ingress-gateway\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: able to define multiple ingress gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'contains("-ingress-gateway-name=\"gateway1\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'contains("-ingress-gateway-name=\"gateway2\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'indices("-ingress-gateway-name") | length' | tee /dev/stderr) + [ "${actual}" = 2 ] +} + +@test "serverACLInit/Job: ingress gateways acl option enabled with .ingressGateways.enabled=true, namespaces enabled, default namespace" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-ingress-gateway-name=\"ingress-gateway.default\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: ingress gateways acl option enabled with .ingressGateways.enabled=true, namespaces enabled, no default namespace set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'ingressGateways.defaults.consulNamespace=' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-ingress-gateway-name=\"ingress-gateway\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: multiple ingress gateways with namespaces enabled provides the correct flag format" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'ingressGateways.defaults.consulNamespace=default-namespace' \ + --set 'ingressGateways.gateways[0].name=gateway1' \ + --set 'ingressGateways.gateways[1].name=gateway2' \ + --set 'ingressGateways.gateways[1].consulNamespace=namespace2' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'contains("-ingress-gateway-name=\"gateway1.default-namespace\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'contains("-ingress-gateway-name=\"gateway2.namespace2\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'indices("-ingress-gateway-name") | length' | tee /dev/stderr) + [ "${actual}" = 2 ] +} + #-------------------------------------------------------------------- # global.tls.enabled diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index 2fed0c3ac1..8c17bb3d95 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -118,7 +118,6 @@ load _helpers --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=remote' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.data["proxy-defaults-config.json"]' | yq -r '.config_entries.bootstrap[0].mesh_gateway.mode' | tee /dev/stderr) [ "${actual}" = "remote" ] @@ -132,7 +131,6 @@ load _helpers --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.data["proxy-defaults-config.json"]' | yq '.config_entries.bootstrap[0].mesh_gateway' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -146,7 +144,6 @@ load _helpers --set 'connectInject.centralConfig.proxyDefaults="{\"hello\": \"world\"}"' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=null' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.data["proxy-defaults-config.json"]' | yq '.config_entries.bootstrap[0].mesh_gateway' | tee /dev/stderr) [ "${actual}" = "null" ] @@ -160,7 +157,6 @@ load _helpers --set 'connectInject.centralConfig.proxyDefaults=""' \ --set 'meshGateway.enabled=true' \ --set 'meshGateway.globalMode=remote' \ - --set 'client.grpc=true' \ . | tee /dev/stderr | yq -r '.data["proxy-defaults-config.json"]' | yq -r '.config_entries.bootstrap[0].mesh_gateway.mode' | tee /dev/stderr) [ "${actual}" = "remote" ] diff --git a/values.yaml b/values.yaml index d43246732c..06816d8104 100644 --- a/values.yaml +++ b/values.yaml @@ -55,6 +55,10 @@ global: # If using Consul Enterprise namespaces, must be >= 0.12. imageK8S: "hashicorp/consul-k8s:0.16.0" + # imageEnvoy defines the default envoy image to use for ingress and + # terminating gateways. + imageEnvoy: "envoyproxy/envoy:v1.13.0" + # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running # since Consul doesn't support an automatic way to change this value @@ -1092,6 +1096,107 @@ meshGateway: # "annotation-key": "annotation-value" annotations: null +# Configuration options for ingress gateways. Default values for all +# ingress gateways are defined in `ingressGateways.defaults`. Any of +# these values may be overridden in `ingressGateways.gateways` for a +# specific gateway with the exception of annotations. Annotations will +# include both the default annotations and any additional ones defined +# for a specific gateway. +# Requirements: consul >= 1.8.0 and consul-k8s >= 0.16.0 if using +# global.acls.manageSystemACLs. +ingressGateways: + # Enable ingress gateway deployment. Requires `connectInject.enabled=true`. + enabled: false + + # Defaults sets default values for all gateway fields. With the exception + # of annotations, defining any of these values in the `gateways` list + # will override the default values provided here. + defaults: + # Number of replicas for each ingress gateway defined. + replicas: 2 + + # The service options configure the Service that fronts the gateway Deployment. + service: + # Type of service: LoadBalancer, ClusterIP or NodePort. If using NodePort service + # type, you must set the desired nodePorts in the `ports` setting below. + type: ClusterIP + + # Ports that will be exposed on the service and gateway container. Any + # ports defined as ingress listeners on the gateway's Consul configuration + # entry should be included here. The first port will be used as part of + # the Consul service registration for the gateway and be listed in its + # SRV record. If using a NodePort service type, you must specify the + # desired nodePort for each exposed port. + ports: + - port: 8080 + nodePort: null + - port: 8443 + nodePort: null + + # Annotations to apply to the ingress gateway service. Annotations defined + # here will be applied to all ingress gateway services in addition to any + # service annotations defined for a specific gateway in `ingressGateways.gateways`. + # Example: + # annotations: | + # "annotation-key": "annotation-value" + annotations: null + + # Optional YAML string that will be appended to the Service spec. + additionalSpec: null + + # Resource limits for all ingress gateway pods + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # By default, we set an anti affinity so that two of the same gateway pods + # won't be on the same node. NOTE: Gateways require that Consul client agents are + # also running on the nodes alongside each gateway Pod. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: ingress-gateway + topologyKey: kubernetes.io/hostname + + # Optional YAML string to specify tolerations. + tolerations: null + + # Optional YAML string to specify a nodeSelector config. + nodeSelector: null + + # Optional priorityClassName. + priorityClassName: "" + + # Annotations to apply to the ingress gateway deployment. Annotations defined + # here will be applied to all ingress gateway deployments in addition to any + # annotations defined for a specific gateway in `ingressGateways.gateways`. + # Example: + # annotations: | + # "annotation-key": "annotation-value" + annotations: null + + # [Enterprise Only] `consulNamespace` defines the Consul namespace to register + # the gateway into. Requires `global.enableConsulNamespaces` to be true and + # Consul Enterprise v1.7+ with a valid Consul Enterprise license. + # Note: The Consul namespace MUST exist before the gateway is deployed or + # deployment will fail. + consulNamespace: "default" + + # Gateways is a list of gateway objects. The only required field for + # each is `name`, though they can also contain any of the fields in + # `defaults`. Values defined here override the defaults except in the + # case of annotations where both will be applied. + gateways: + - name: ingress-gateway + # Control whether a test Pod manifest is generated when running helm template. # When using helm install, the test Pod is not submitted to the cluster so this # is only useful when running helm template. From 9b69003f5a37083bfce886f9dbd8c6fc425f65f7 Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig <16315901+adilyse@users.noreply.github.com> Date: Mon, 11 May 2020 14:52:20 -0700 Subject: [PATCH 376/739] Support terminating gateways This creates all of the necessary templates to support terminating gateways in the helm chart. Using `terminatingGateways.defaults` and `terminatingGateways.gateways`, it's possible to define multiple gateways. Names must be provided for each and they must be unique. Any gateway-specific values will override the default value with the exception of annotations. Annotations will apply both the defaults and gateway-specific annotations. --- templates/server-acl-init-job.yaml | 17 + .../terminating-gateways-deployment.yaml | 357 +++++++ ...erminating-gateways-podsecuritypolicy.yaml | 44 + templates/terminating-gateways-role.yaml | 43 + .../terminating-gateways-rolebinding.yaml | 26 + .../terminating-gateways-serviceaccount.yaml | 24 + test/unit/helpers.bats | 2 +- test/unit/ingress-gateways-deployment.bats | 46 +- test/unit/mesh-gateway-deployment.bats | 31 +- test/unit/server-acl-init-job.bats | 106 ++ .../unit/terminating-gateways-deployment.bats | 993 ++++++++++++++++++ ...erminating-gateways-podsecuritypolicy.bats | 52 + test/unit/terminating-gateways-role.bats | 105 ++ .../terminating-gateways-rolebinding.bats | 44 + .../terminating-gateways-serviceaccount.bats | 70 ++ values.yaml | 105 +- 16 files changed, 2046 insertions(+), 19 deletions(-) create mode 100644 templates/terminating-gateways-deployment.yaml create mode 100644 templates/terminating-gateways-podsecuritypolicy.yaml create mode 100644 templates/terminating-gateways-role.yaml create mode 100644 templates/terminating-gateways-rolebinding.yaml create mode 100644 templates/terminating-gateways-serviceaccount.yaml create mode 100644 test/unit/terminating-gateways-deployment.bats create mode 100644 test/unit/terminating-gateways-podsecuritypolicy.bats create mode 100644 test/unit/terminating-gateways-role.bats create mode 100644 test/unit/terminating-gateways-rolebinding.bats create mode 100644 test/unit/terminating-gateways-serviceaccount.bats diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 3e2b012908..061550dd12 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -158,6 +158,23 @@ spec: {{- end }} {{- end }} + {{- if .Values.terminatingGateways.enabled }} + {{- if .Values.global.enableConsulNamespaces }} + {{- $root := . }} + {{- range .Values.terminatingGateways.gateways }} + {{- if (or $root.Values.terminatingGateways.defaults.consulNamespace .consulNamespace) }} + -terminating-gateway-name="{{ .name }}.{{ (default $root.Values.terminatingGateways.defaults.consulNamespace .consulNamespace) }}" \ + {{- else }} + -terminating-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.terminatingGateways.gateways }} + -terminating-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.connectInject.aclBindingRuleSelector }} -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \ {{- end }} diff --git a/templates/terminating-gateways-deployment.yaml b/templates/terminating-gateways-deployment.yaml new file mode 100644 index 0000000000..e236ac4fb9 --- /dev/null +++ b/templates/terminating-gateways-deployment.yaml @@ -0,0 +1,357 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} +{{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} + +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} +{{- $names := dict }} + +{{- range .Values.terminatingGateways.gateways }} + +{{- if empty .name }} +# Check that name is not empty +{{ fail "Terminating gateway names cannot be empty"}} +{{ end -}} +{{- if hasKey $names .name }} +# Check that the name doesn't already exist +{{ fail "Terminating gateway names must be unique"}} +{{ end -}} +{{- /* Add the gateway name to the $names dict to ensure uniqueness */ -}} +{{- $_ := set $names .name .name }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + replicas: {{ default $defaults.replicas .replicas }} + selector: + matchLabels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + template: + metadata: + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + {{- if $defaults.annotations }} + # We allow both default annotations and gateway-specific annotations + {{- tpl $defaults.annotations $root | nindent 8 }} + {{- end }} + {{- if .annotations }} + {{- tpl .annotations $root | nindent 8 }} + {{- end }} + spec: + {{- if (or $defaults.affinity .affinity) }} + affinity: + {{ tpl (default $defaults.affinity .affinity) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.tolerations .tolerations) }} + tolerations: + {{ tpl (default $defaults.tolerations .tolerations) $root | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} + volumes: + - name: consul-bin + emptyDir: {} + - name: consul-service + emptyDir: + medium: "Memory" + {{- range (default $defaults.extraVolumes .extraVolumes) }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- with .items }} + items: + {{- range . }} + - key: {{.key}} + path: {{.path}} + {{- end }} + {{- end }} + {{- end }} + {{- if $root.Values.global.tls.enabled }} + {{- if not (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + secret: + {{- if $root.Values.global.tls.caCert.secretName }} + secretName: {{ $root.Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" $root }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" $root.Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} + initContainers: + # We use the Envoy image as our base image so we use an init container to + # copy the Consul binary to a shared directory that can be used when + # starting Envoy. + - name: copy-consul-bin + image: {{ $root.Values.global.image | quote }} + command: + - cp + - /bin/consul + - /consul-bin/consul + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + {{- if (and $root.Values.global.tls.enabled $root.Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" $root | nindent 8 }} + {{- end }} + # service-init registers the terminating gateway service. + - name: service-init + image: {{ $root.Values.global.imageK8S }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + consul-k8s acl-init \ + -secret-name="{{ template "consul.fullname" $root }}-{{ .name }}-terminating-gateway-acl-token" \ + -k8s-namespace={{ $root.Release.Namespace }} \ + -token-sink-file=/consul/service/acl-token + {{- end }} + + cat > /consul/service/service.hcl << EOF + service { + kind = "terminating-gateway" + name = "{{ .name }}" + id = "${POD_NAME}" + {{- if $root.Values.global.enableConsulNamespaces }} + namespace = "{{ (default $defaults.consulNamespace .consulNamespace) }}" + {{- end }} + address = "${POD_IP}" + port = 8443 + checks = [ + { + name = "Terminating Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] + } + EOF + + /consul-bin/consul services register \ + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + -token-file=/consul/service/acl-token \ + {{- end }} + /consul/service/service.hcl + volumeMounts: + - name: consul-service + mountPath: /consul/service + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + containers: + - name: terminating-gateway + image: {{ $root.Values.global.imageEnvoy | quote }} + {{- if (default $defaults.resources .resources) }} + resources: {{ toYaml (default $defaults.resources .resources) | nindent 12 }} + {{- end }} + volumeMounts: + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- range (default $defaults.extraVolumes .extraVolumes) }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ template "consul.fullname" $root }}-{{ .name }}-terminating-gateway-acl-token" + key: "token" + {{- end}} + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_GRPC_ADDR + value: https://$(HOST_IP):8502 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + - name: CONSUL_GRPC_ADDR + value: $(HOST_IP):8502 + {{- end }} + command: + - /consul-bin/consul + - connect + - envoy + - -gateway=terminating + - -proxy-id=$(POD_NAME) + {{- if $root.Values.global.enableConsulNamespaces }} + - -namespace={{ default $defaults.consulNamespace .consulNamespace }} + {{- end }} + livenessProbe: + tcpSocket: + port: 8443 + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 8443 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - name: gateway + containerPort: 8443 + lifecycle: + preStop: + exec: + command: + - "/bin/sh" + - "-ec" + - | + /consul-bin/consul services deregister \ + {{- if $root.Values.global.enableConsulNamespaces }} + -namespace={{ default $defaults.consulNamespace .consulNamespace }} \ + {{- end }} + -id="${POD_NAME}" + + # lifecycle-sidecar ensures the terminating gateway is always registered with + # the local Consul agent, even if it loses the initial registration. + - name: lifecycle-sidecar + image: {{ $root.Values.global.imageK8S }} + volumeMounts: + - name: consul-service + mountPath: /consul/service + readOnly: true + - name: consul-bin + mountPath: /consul-bin + {{- if $root.Values.global.tls.enabled }} + {{- if $root.Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if $root.Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + command: + - consul-k8s + - lifecycle-sidecar + - -service-config=/consul/service/service.hcl + - -consul-binary=/consul-bin/consul + {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - -token-file=/consul/service/acl-token + {{- end }} + {{- if (default $defaults.priorityClassName .priorityClassName) }} + priorityClassName: {{ (default $defaults.priorityClassName .priorityClassName) | quote }} + {{- end }} + {{- if (default $defaults.nodeSelector .nodeSelector) }} + nodeSelector: + {{ tpl (default $defaults.nodeSelector .nodeSelector) $root | indent 8 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/terminating-gateways-podsecuritypolicy.yaml b/templates/terminating-gateways-podsecuritypolicy.yaml new file mode 100644 index 0000000000..b825cef907 --- /dev/null +++ b/templates/terminating-gateways-podsecuritypolicy.yaml @@ -0,0 +1,44 @@ +{{- if (and .Values.global.enablePodSecurityPolicies .Values.terminatingGateways.enabled) }} +{{- $root := . }} +{{- range .Values.terminatingGateways.gateways }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +--- +{{- end }} +{{- end }} diff --git a/templates/terminating-gateways-role.yaml b/templates/terminating-gateways-role.yaml new file mode 100644 index 0000000000..f381518311 --- /dev/null +++ b/templates/terminating-gateways-role.yaml @@ -0,0 +1,43 @@ +{{- if .Values.terminatingGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} + +{{- range .Values.terminatingGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs $root.Values.global.enablePodSecurityPolicies) }} +rules: +{{- if $root.Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - use +{{- end }} +{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }}-terminating-gateway-acl-token + verbs: + - get +{{- end }} +{{- else }} +rules: [] +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/templates/terminating-gateways-rolebinding.yaml b/templates/terminating-gateways-rolebinding.yaml new file mode 100644 index 0000000000..4271f8f59c --- /dev/null +++ b/templates/terminating-gateways-rolebinding.yaml @@ -0,0 +1,26 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- $root := . }} +{{- range .Values.terminatingGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" $root }}-{{ .name }} +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} +--- +{{- end }} +{{- end }} diff --git a/templates/terminating-gateways-serviceaccount.yaml b/templates/terminating-gateways-serviceaccount.yaml new file mode 100644 index 0000000000..ee7ca4bd02 --- /dev/null +++ b/templates/terminating-gateways-serviceaccount.yaml @@ -0,0 +1,24 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- $root := . }} +{{- range .Values.terminatingGateways.gateways }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +{{- with $root.Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index ab49d8f742..3d190fa0b0 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -270,6 +270,6 @@ load _helpers diff=$(diff <(grep -r '\.Values\.global\.bootstrapACLs' templates/*) <(grep -r -e 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) [ "$diff" = "" ] - diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) + diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r -e 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) [ "$diff" = "" ] } diff --git a/test/unit/ingress-gateways-deployment.bats b/test/unit/ingress-gateways-deployment.bats index d27e16404d..5ef46fa7a5 100644 --- a/test/unit/ingress-gateways-deployment.bats +++ b/test/unit/ingress-gateways-deployment.bats @@ -103,7 +103,7 @@ load _helpers #-------------------------------------------------------------------- # global.tls.enabled -@test "ingressGateways/Deployment: sets TLS flags when global.tls.enabled" { +@test "ingressGateways/Deployment: sets TLS env variables when global.tls.enabled" { cd `chart_dir` local env=$(helm template \ -x templates/ingress-gateways-deployment.yaml \ @@ -123,6 +123,23 @@ load _helpers [ "${actual}" = "/consul/tls/ca/tls.crt" ] } +@test "ingressGateways/Deployment: sets TLS env variables in lifecycle sidecar when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[1].env[]' | tee /dev/stderr) + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + @test "ingressGateways/Deployment: can overwrite CA secret with the provided one" { cd `chart_dir` local ca_cert_volume=$(helm template \ @@ -205,6 +222,33 @@ load _helpers [ "${actual}" = "" ] } +#-------------------------------------------------------------------- +# global.acls.manageSystemACLs + +@test "ingressGateways/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s '[.[0].spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: lifecycle-sidecar uses -token-file flag when global.acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[1].command | any(contains("-token-file=/consul/service/acl-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # replicas diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 2a516bb6e2..876cf29221 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -477,7 +477,7 @@ key2: value2' \ #-------------------------------------------------------------------- # global.tls.enabled -@test "meshGateway/Deployment: sets TLS flags when global.tls.enabled" { +@test "meshGateway/Deployment: sets TLS env variables when global.tls.enabled" { cd `chart_dir` local env=$(helm template \ -x templates/mesh-gateway-deployment.yaml \ @@ -487,16 +487,31 @@ key2: value2' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].env[]' | tee /dev/stderr) - local actual - actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) [ "${actual}" = 'https://$(HOST_IP):8501' ] - local actual - actual=$(echo $env | jq -r '. | select(.name == "CONSUL_GRPC_ADDR") | .value' | tee /dev/stderr) - [ "${actual}" = 'https://$(HOST_IP):8502' ] + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_GRPC_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8502' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "meshGateway/Deployment: sets TLS env variables in lifecycle sidecar when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[1].env[]' | tee /dev/stderr) + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] - actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) - [ "${actual}" = "/consul/tls/ca/tls.crt" ] + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] } @test "meshGateway/Deployment: can overwrite CA secret with the provided one" { diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 1cc4171400..7ade416896 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -390,6 +390,112 @@ load _helpers [ "${actual}" = 2 ] } +#-------------------------------------------------------------------- +# terminatingGateways.enabled + +@test "serverACLInit/Job: terminating gateways acl options disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-terminating-gateway-name"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "serverACLInit/Job: terminating gateways acl option enabled with .terminatingGateways.enabled=true (single default gateway)" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-terminating-gateway-name=\"terminating-gateway\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: able to define multiple terminating gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'contains("-terminating-gateway-name=\"gateway1\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'contains("-terminating-gateway-name=\"gateway2\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'indices("-terminating-gateway-name") | length' | tee /dev/stderr) + [ "${actual}" = 2 ] +} + +@test "serverACLInit/Job: terminating gateways acl option enabled with .terminatingGateways.enabled=true, namespaces enabled, default namespace" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-terminating-gateway-name=\"terminating-gateway.default\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: terminating gateways acl option enabled with .terminatingGateways.enabled=true, namespaces enabled, no default namespace set" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command | any(contains("-terminating-gateway-name=\"terminating-gateway\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: multiple terminating gateways with namespaces enabled provides the correct flag format" { + cd `chart_dir` + local object=$(helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=default-namespace' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + --set 'terminatingGateways.gateways[1].consulNamespace=namespace2' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + + local actual=$(echo $object | + yq 'contains("-terminating-gateway-name=\"gateway1.default-namespace\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'contains("-terminating-gateway-name=\"gateway2.namespace2\"")' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq 'indices("-terminating-gateway-name") | length' | tee /dev/stderr) + [ "${actual}" = 2 ] +} + #-------------------------------------------------------------------- # global.tls.enabled diff --git a/test/unit/terminating-gateways-deployment.bats b/test/unit/terminating-gateways-deployment.bats new file mode 100644 index 0000000000..eab45e606a --- /dev/null +++ b/test/unit/terminating-gateways-deployment.bats @@ -0,0 +1,993 @@ +#!/usr/bin/env bats + +load _helpers + +@test "terminatingGateways/Deployment: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/Deployment: enabled with terminatingGateways, connectInject and client.grpc enabled, has default gateway name" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s '.[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-terminating-gateway" ] +} + +#-------------------------------------------------------------------- +# prerequisites + +@test "terminatingGateways/Deployment: fails if connectInject.enabled=false" { + cd `chart_dir` + run helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "connectInject.enabled must be true" ]] +} + +@test "terminatingGateways/Deployment: fails if client.grpc=false" { + cd `chart_dir` + run helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'client.grpc=false' \ + --set 'connectInject.enabled=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "client.grpc must be true" ]] +} + +@test "terminatingGateways/Deployment: fails if global.enabled is false and clients are not explicitly enabled" { + cd `chart_dir` + run helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +@test "terminatingGateways/Deployment: fails if global.enabled is true but clients are explicitly disabled" { + cd `chart_dir` + run helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enabled=true' \ + --set 'client.enabled=false' . + [ "$status" -eq 1 ] + [[ "$output" =~ "clients must be enabled" ]] +} + +#-------------------------------------------------------------------- +# envoyImage + +@test "terminatingGateways/Deployment: envoy image has default global value" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] +} + +@test "terminatingGateways/Deployment: envoy image can be set using the global value" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imageEnvoy=new/image' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) + [ "${actual}" = "new/image" ] +} + +#-------------------------------------------------------------------- +# global.tls.enabled + +@test "terminatingGateways/Deployment: sets TLS env variables when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].env[]' | tee /dev/stderr) + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_GRPC_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8502' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "terminatingGateways/Deployment: sets TLS env variables in lifecycle sidecar when global.tls.enabled" { + cd `chart_dir` + local env=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[1].env[]' | tee /dev/stderr) + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_HTTP_ADDR") | .value' | tee /dev/stderr) + [ "${actual}" = 'https://$(HOST_IP):8501' ] + + local actual=$(echo $env | jq -r '. | select(.name == "CONSUL_CACERT") | .value' | tee /dev/stderr) + [ "${actual}" = "/consul/tls/ca/tls.crt" ] +} + +@test "terminatingGateways/Deployment: can overwrite CA secret with the provided one" { + cd `chart_dir` + local ca_cert_volume=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.caCert.secretName=foo-ca-cert' \ + --set 'global.tls.caCert.secretKey=key' \ + --set 'global.tls.caKey.secretName=foo-ca-key' \ + --set 'global.tls.caKey.secretKey=key' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name=="consul-ca-cert")' | tee /dev/stderr) + + # check that the provided ca cert secret is attached as a volume + local actual=$(echo $ca_cert_volume | yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo-ca-cert" ] + + # check that the volume uses the provided secret key + local actual=$(echo $ca_cert_volume | yq -r '.secret.items[0].key' | tee /dev/stderr) + [ "${actual}" = "key" ] +} + +#-------------------------------------------------------------------- +# global.tls.enableAutoEncrypt + +@test "terminatingGateways/Deployment: consul-auto-encrypt-ca-cert volume is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: consul-auto-encrypt-ca-cert volumeMount is added when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[0].volumeMounts[] | select(.name == "consul-auto-encrypt-ca-cert") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: get-auto-encrypt-client-ca init container is created when TLS with auto-encrypt is enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.initContainers[] | select(.name == "get-auto-encrypt-client-ca") | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: consul-ca-cert volume is not added if externalServers.enabled=true and externalServers.useSystemRoots=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'externalServers.enabled=true' \ + --set 'externalServers.hosts[0]=foo.com' \ + --set 'externalServers.useSystemRoots=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.volumes[] | select(.name == "consul-ca-cert")' | tee /dev/stderr) + [ "${actual}" = "" ] +} + +#-------------------------------------------------------------------- +# global.acls.manageSystemACLs + +@test "terminatingGateways/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s '[.[0].spec.template.spec.containers[0].env[].name] | any(contains("CONSUL_HTTP_TOKEN"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: lifecycle-sidecar uses -token-file flag when global.acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[1].command | any(contains("-token-file=/consul/service/acl-token"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# replicas + +@test "terminatingGateways/Deployment: replicas defaults to 2" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "terminatingGateways/Deployment: replicas can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.replicas=3' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "3" ] +} + +@test "terminatingGateways/Deployment: replicas can be set through specific gateway, overrides default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.replicas=3' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].replicas=12' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.replicas' | tee /dev/stderr) + [ "${actual}" = "12" ] +} + +#-------------------------------------------------------------------- +# extraVolumes + +@test "terminatingGateways/Deployment: adds extra volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=configMap' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.configMap.name' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + local actual=$(echo $object | + yq -r '.configMap.secretName' | tee /dev/stderr) + [ "${actual}" = "null" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=configMap' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] +} + +@test "terminatingGateways/Deployment: adds extra secret volume" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=secret' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.secret.name' | tee /dev/stderr) + [ "${actual}" = "null" ] + + local actual=$(echo $object | + yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=configMap' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] +} + +@test "terminatingGateways/Deployment: adds extra secret volume with items" { + cd `chart_dir` + + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=secret' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=foo' \ + --set 'terminatingGateways.defaults.extraVolumes[0].items[0].key=key' \ + --set 'terminatingGateways.defaults.extraVolumes[0].items[0].path=path' \ + . | tee /dev/stderr | + yq -c -s '.[0].spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + [ "${actual}" = "{\"name\":\"userconfig-foo\",\"secret\":{\"secretName\":\"foo\",\"items\":[{\"key\":\"key\",\"path\":\"path\"}]}}" ] +} + +@test "terminatingGateways/Deployment: adds extra secret volume through specific gateway overriding defaults" { + cd `chart_dir` + + # Test that it defines it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=secret' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=default-foo' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].extraVolumes[0].type=secret' \ + --set 'terminatingGateways.gateways[0].extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.volumes[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.secret.name' | tee /dev/stderr) + [ "${actual}" = "null" ] + + local actual=$(echo $object | + yq -r '.secret.secretName' | tee /dev/stderr) + [ "${actual}" = "foo" ] + + # Test that it mounts it + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.extraVolumes[0].type=configMap' \ + --set 'terminatingGateways.defaults.extraVolumes[0].name=default-foo' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].extraVolumes[0].type=secret' \ + --set 'terminatingGateways.gateways[0].extraVolumes[0].name=foo' \ + . | tee /dev/stderr | + yq -r -s '.[0].spec.template.spec.containers[0].volumeMounts[] | select(.name == "userconfig-foo")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.readOnly' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.mountPath' | tee /dev/stderr) + [ "${actual}" = "/consul/userconfig/foo" ] +} + +#-------------------------------------------------------------------- +# resources + +@test "terminatingGateways/Deployment: resources has default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + [ $(echo "${actual}" | yq -r '.requests.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.requests.cpu') = "100m" ] + [ $(echo "${actual}" | yq -r '.limits.memory') = "100Mi" ] + [ $(echo "${actual}" | yq -r '.limits.cpu') = "100m" ] +} + +@test "terminatingGateways/Deployment: resources can be set through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.resources.requests.memory=memory' \ + --set 'terminatingGateways.defaults.resources.requests.cpu=cpu' \ + --set 'terminatingGateways.defaults.resources.limits.memory=memory2' \ + --set 'terminatingGateways.defaults.resources.limits.cpu=cpu2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.requests.memory' | tee /dev/stderr) + [ "${actual}" = "memory" ] + + local actual=$(echo $object | yq -r '.requests.cpu' | tee /dev/stderr) + [ "${actual}" = "cpu" ] + + local actual=$(echo $object | yq -r '.limits.memory' | tee /dev/stderr) + [ "${actual}" = "memory2" ] + + local actual=$(echo $object | yq -r '.limits.cpu' | tee /dev/stderr) + [ "${actual}" = "cpu2" ] +} + +@test "terminatingGateways/Deployment: resources can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.resources.requests.memory=memory' \ + --set 'terminatingGateways.defaults.resources.requests.cpu=cpu' \ + --set 'terminatingGateways.defaults.resources.limits.memory=memory2' \ + --set 'terminatingGateways.defaults.resources.limits.cpu=cpu2' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].resources.requests.memory=gwmemory' \ + --set 'terminatingGateways.gateways[0].resources.requests.cpu=gwcpu' \ + --set 'terminatingGateways.gateways[0].resources.limits.memory=gwmemory2' \ + --set 'terminatingGateways.gateways[0].resources.limits.cpu=gwcpu2' \ + . | tee /dev/stderr | + yq -s '.[0].spec.template.spec.containers[0].resources' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.requests.memory' | tee /dev/stderr) + [ "${actual}" = "gwmemory" ] + + local actual=$(echo $object | yq -r '.requests.cpu' | tee /dev/stderr) + [ "${actual}" = "gwcpu" ] + + local actual=$(echo $object | yq -r '.limits.memory' | tee /dev/stderr) + [ "${actual}" = "gwmemory2" ] + + local actual=$(echo $object | yq -r '.limits.cpu' | tee /dev/stderr) + [ "${actual}" = "gwcpu2" ] +} + +#-------------------------------------------------------------------- +# affinity + +@test "terminatingGateways/Deployment: affinity defaults to one per node" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey' | tee /dev/stderr) + [ "${actual}" = "kubernetes.io/hostname" ] +} + +@test "terminatingGateways/Deployment: affinity can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.affinity=key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "terminatingGateways/Deployment: affinity can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.affinity=key: value' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].affinity=key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.affinity.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# tolerations + +@test "terminatingGateways/Deployment: no tolerations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "terminatingGateways/Deployment: tolerations can be set through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.tolerations=- key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations[0].key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "terminatingGateways/Deployment: tolerations can be set through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.tolerations=- key: value' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].tolerations=- key: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.tolerations[0].key' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# nodeSelector + +@test "terminatingGateways/Deployment: no nodeSelector by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "terminatingGateways/Deployment: can set a nodeSelector through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.nodeSelector=key: value' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector.key' | tee /dev/stderr) + [ "${actual}" = "value" ] +} + +@test "terminatingGateways/Deployment: can set a nodeSelector through specific gateway, overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.nodeSelector=key: value' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].nodeSelector=key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.nodeSelector.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# priorityClassName + +@test "terminatingGateways/Deployment: no priorityClassName by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "terminatingGateways/Deployment: can set a priorityClassName through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.priorityClassName=name' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "name" ] +} + +@test "terminatingGateways/Deployment: can set a priorityClassName per gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.priorityClassName=name' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].priorityClassName=priority' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.priorityClassName' | tee /dev/stderr) + [ "${actual}" = "priority" ] +} + +#-------------------------------------------------------------------- +# annotations + +@test "terminatingGateways/Deployment: no extra annotations by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations | length' | tee /dev/stderr) + [ "${actual}" = "1" ] +} + +@test "terminatingGateways/Deployment: extra annotations can be set through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "terminatingGateways/Deployment: extra annotations can be set through specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "3" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +@test "terminatingGateways/Deployment: extra annotations can be set through defaults and specific gateway" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.defaults.annotations=defaultkey: defaultvalue' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[0].annotations=key1: value1 +key2: value2' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.metadata.annotations' | tee /dev/stderr) + + local actual=$(echo $object | yq '. | length' | tee /dev/stderr) + [ "${actual}" = "4" ] + + local actual=$(echo $object | yq -r '.defaultkey' | tee /dev/stderr) + [ "${actual}" = "defaultvalue" ] + + local actual=$(echo $object | yq -r '.key1' | tee /dev/stderr) + [ "${actual}" = "value1" ] + + local actual=$(echo $object | yq -r '.key2' | tee /dev/stderr) + [ "${actual}" = "value2" ] +} + +#-------------------------------------------------------------------- +# service-init init container command + +@test "terminatingGateways/Deployment: service-init init container defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp=' +cat > /consul/service/service.hcl << EOF +service { + kind = "terminating-gateway" + name = "terminating-gateway" + id = "${POD_NAME}" + address = "${POD_IP}" + port = 8443 + checks = [ + { + name = "Terminating Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "terminatingGateways/Deployment: service-init init container with acls.manageSystemACLs=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp='consul-k8s acl-init \ + -secret-name="release-name-consul-terminating-gateway-terminating-gateway-acl-token" \ + -k8s-namespace=default \ + -token-sink-file=/consul/service/acl-token + +cat > /consul/service/service.hcl << EOF +service { + kind = "terminating-gateway" + name = "terminating-gateway" + id = "${POD_NAME}" + address = "${POD_IP}" + port = 8443 + checks = [ + { + name = "Terminating Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + -token-file=/consul/service/acl-token \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "terminatingGateways/Deployment: service-init init container gateway namespace can be specified through defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp=' +cat > /consul/service/service.hcl << EOF +service { + kind = "terminating-gateway" + name = "terminating-gateway" + id = "${POD_NAME}" + namespace = "namespace" + address = "${POD_IP}" + port = 8443 + checks = [ + { + name = "Terminating Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +@test "terminatingGateways/Deployment: service-init init container gateway namespace can be specified through specific gateway overriding defaults" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=namespace' \ + --set 'terminatingGateways.gateways[0].name=terminating-gateway' \ + --set 'terminatingGateways.gateways[0].consulNamespace=new-namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.initContainers | map(select(.name == "service-init"))[0] | .command[2]' | tee /dev/stderr) + + exp=' +cat > /consul/service/service.hcl << EOF +service { + kind = "terminating-gateway" + name = "terminating-gateway" + id = "${POD_NAME}" + namespace = "new-namespace" + address = "${POD_IP}" + port = 8443 + checks = [ + { + name = "Terminating Gateway Listening" + interval = "10s" + tcp = "${POD_IP}:8443" + deregister_critical_service_after = "6h" + } + ] +} +EOF + +/consul-bin/consul services register \ + /consul/service/service.hcl' + + [ "${actual}" = "${exp}" ] +} + +#-------------------------------------------------------------------- +# namespaces + +@test "terminatingGateways/Deployment: namespace command flag is not present by default" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace"))' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/Deployment: namespace command flag is specified through defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace=namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace=namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: namespace command flag is specified through specific gateway overriding defaults" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'terminatingGateways.defaults.consulNamespace=namespace' \ + --set 'terminatingGateways.gateways[0].name=terminating-gateway' \ + --set 'terminatingGateways.gateways[0].consulNamespace=new-namespace' \ + . | tee /dev/stderr | + yq -s -r '.[0].spec.template.spec.containers[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.command | any(contains("-namespace=new-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + + local actual=$(echo $object | yq -r '.lifecycle.preStop.exec.command | any(contains("-namespace=new-namespace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# multiple gateways + +@test "terminatingGateways/Deployment: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[0] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[1] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/terminating-gateways-podsecuritypolicy.bats b/test/unit/terminating-gateways-podsecuritypolicy.bats new file mode 100644 index 0000000000..d2afa51fa7 --- /dev/null +++ b/test/unit/terminating-gateways-podsecuritypolicy.bats @@ -0,0 +1,52 @@ +#!/usr/bin/env bats + +load _helpers + +@test "terminatingGateways/PodSecurityPolicy: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-podsecuritypolicy.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/PodSecurityPolicy: enabled with terminatingGateways, connectInject and client.grpc enabled and global.enablePodSecurityPolicies=true" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-podsecuritypolicy.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/PodSecurityPolicy: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-podsecuritypolicy.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq '.[0] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[1] | length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] +} diff --git a/test/unit/terminating-gateways-role.bats b/test/unit/terminating-gateways-role.bats new file mode 100644 index 0000000000..0436337154 --- /dev/null +++ b/test/unit/terminating-gateways-role.bats @@ -0,0 +1,105 @@ +#!/usr/bin/env bats + +load _helpers + +@test "terminatingGateways/Role: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/Role: enabled with terminatingGateways, connectInject and client.grpc enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Role: rules for PodSecurityPolicy" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules[0].resources[0]' | tee /dev/stderr) + [ "${actual}" = "podsecuritypolicies" ] +} + +@test "terminatingGateways/Role: rules for global.acls.manageSystemACLs=true" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules[0]' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.resources[0]' | tee /dev/stderr) + [ "${actual}" = "secrets" ] + + local actual=$(echo $object | yq -r '.resourceNames[0]' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-terminating-gateway-terminating-gateway-acl-token" ] +} + +@test "terminatingGateways/Role: rules is empty if no ACLs, PSPs" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules' | tee /dev/stderr) + [ "${actual}" = "[]" ] +} + +@test "terminatingGateways/Role: rules for ACLs, PSPs" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + . | tee /dev/stderr | + yq -s -r '.[0].rules | length' | tee /dev/stderr) + [ "${actual}" = "2" ] +} + +@test "terminatingGateways/Role: rules for ACLs, PSPs with multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.enablePodSecurityPolicies=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[0].rules | length' | tee /dev/stderr) + [ "${actual}" = "2" ] + + local actual=$(echo $object | yq '.[1].rules | length' | tee /dev/stderr) + [ "${actual}" = "2" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/terminating-gateways-rolebinding.bats b/test/unit/terminating-gateways-rolebinding.bats new file mode 100644 index 0000000000..8d63b1d737 --- /dev/null +++ b/test/unit/terminating-gateways-rolebinding.bats @@ -0,0 +1,44 @@ +#!/usr/bin/env bats + +load _helpers + +@test "terminatingGateways/RoleBinding: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-rolebinding.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/RoleBinding: enabled with terminatingGateways, connectInject and client.grpc enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-rolebinding.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/RoleBinding: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-role.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo $object | yq '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/terminating-gateways-serviceaccount.bats b/test/unit/terminating-gateways-serviceaccount.bats new file mode 100644 index 0000000000..baa17bfe4e --- /dev/null +++ b/test/unit/terminating-gateways-serviceaccount.bats @@ -0,0 +1,70 @@ +#!/usr/bin/env bats + +load _helpers + +@test "terminatingGateways/ServiceAccount: disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-serviceaccount.yaml \ + . | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "terminatingGateways/ServiceAccount: enabled with terminatingGateways, connectInject and client.grpc enabled" { + cd `chart_dir` + local actual=$(helm template \ + -x templates/terminating-gateways-serviceaccount.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -s 'length > 0' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# global.imagePullSecrets + +@test "terminatingGateways/ServiceAccount: can set image pull secrets" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-serviceaccount.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.imagePullSecrets[0].name=my-secret' \ + --set 'global.imagePullSecrets[1].name=my-secret2' \ + . | tee /dev/stderr) + + local actual=$(echo "$object" | + yq -s -r '.[0].imagePullSecrets[0].name' | tee /dev/stderr) + [ "${actual}" = "my-secret" ] + + local actual=$(echo "$object" | + yq -s -r '.[0].imagePullSecrets[1].name' | tee /dev/stderr) + [ "${actual}" = "my-secret2" ] +} + +#-------------------------------------------------------------------- +# multiple gateways + +@test "terminatingGateways/ServiceAccount: multiple gateways" { + cd `chart_dir` + local object=$(helm template \ + -x templates/terminating-gateways-serviceaccount.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'terminatingGateways.gateways[0].name=gateway1' \ + --set 'terminatingGateways.gateways[1].name=gateway2' \ + . | tee /dev/stderr | + yq -s -r '.' | tee /dev/stderr) + + local actual=$(echo $object | yq -r '.[0].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway1" ] + + local actual=$(echo $object | yq -r '.[1].metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-consul-gateway2" ] + + local actual=$(echo "$object" | + yq -r '.[2] | length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/values.yaml b/values.yaml index 06816d8104..fa84e0d0d3 100644 --- a/values.yaml +++ b/values.yaml @@ -1068,9 +1068,9 @@ meshGateway: memory: "100Mi" cpu: "100m" - # By default, we set an anti affinity so that two gateway pods won't be + # By default, we set an anti-affinity so that two gateway pods won't be # on the same node. NOTE: Gateways require that Consul client agents are - # also running on the nodes alongside each gateway Pod. + # also running on the nodes alongside each gateway pod. affinity: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -1103,14 +1103,17 @@ meshGateway: # include both the default annotations and any additional ones defined # for a specific gateway. # Requirements: consul >= 1.8.0 and consul-k8s >= 0.16.0 if using -# global.acls.manageSystemACLs. +# global.acls.manageSystemACLs and consul-k8s >= 0.10.0 if not. ingressGateways: - # Enable ingress gateway deployment. Requires `connectInject.enabled=true`. + # Enable ingress gateway deployment. Requires `connectInject.enabled=true` + # and `client.enabled=true`. enabled: false # Defaults sets default values for all gateway fields. With the exception # of annotations, defining any of these values in the `gateways` list - # will override the default values provided here. + # will override the default values provided here. Annotations will + # include both the default annotations and any additional ones defined + # for a specific gateway. defaults: # Number of replicas for each ingress gateway defined. replicas: 2 @@ -1153,9 +1156,9 @@ ingressGateways: memory: "100Mi" cpu: "100m" - # By default, we set an anti affinity so that two of the same gateway pods + # By default, we set an anti-affinity so that two of the same gateway pods # won't be on the same node. NOTE: Gateways require that Consul client agents are - # also running on the nodes alongside each gateway Pod. + # also running on the nodes alongside each gateway pod. affinity: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -1186,8 +1189,7 @@ ingressGateways: # [Enterprise Only] `consulNamespace` defines the Consul namespace to register # the gateway into. Requires `global.enableConsulNamespaces` to be true and # Consul Enterprise v1.7+ with a valid Consul Enterprise license. - # Note: The Consul namespace MUST exist before the gateway is deployed or - # deployment will fail. + # Note: The Consul namespace MUST exist before the gateway is deployed. consulNamespace: "default" # Gateways is a list of gateway objects. The only required field for @@ -1197,6 +1199,91 @@ ingressGateways: gateways: - name: ingress-gateway +# Configuration options for terminating gateways. Default values for all +# terminating gateways are defined in `terminatingGateways.defaults`. Any of +# these values may be overridden in `terminatingGateways.gateways` for a +# specific gateway with the exception of annotations. Annotations will +# include both the default annotations and any additional ones defined +# for a specific gateway. +# Requirements: consul >= 1.8.0 and consul-k8s >= 0.16.0 if using +# global.acls.manageSystemACLs and consul-k8s >= 0.10.0 if not. +terminatingGateways: + # Enable terminating gateway deployment. Requires `connectInject.enabled=true` + # and `client.enabled=true`. + enabled: false + + # Defaults sets default values for all gateway fields. With the exception + # of annotations, defining any of these values in the `gateways` list + # will override the default values provided here. Annotations will + # include both the default annotations and any additional ones defined + # for a specific gateway. + defaults: + # Number of replicas for each terminating gateway defined. + replicas: 2 + + # extraVolumes is a list of extra volumes to mount. These will be exposed + # to Consul in the path `/consul/userconfig//`. The value below is + # an array of objects, examples are shown below. + # extraVolumes: + # - type: secret + # name: my-secret + # items: # optional items array + # - key: key + # path: path # secret will now mount to /consul/userconfig/my-secret/path + extraVolumes: [] + + # Resource limits for all terminating gateway pods + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # By default, we set an anti-affinity so that two of the same gateway pods + # won't be on the same node. NOTE: Gateways require that Consul client agents are + # also running on the nodes alongside each gateway pod. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: terminating-gateway + topologyKey: kubernetes.io/hostname + + # Optional YAML string to specify tolerations. + tolerations: null + + # Optional YAML string to specify a nodeSelector config. + nodeSelector: null + + # Optional priorityClassName. + priorityClassName: "" + + # Annotations to apply to the terminating gateway deployment. Annotations defined + # here will be applied to all terminating gateway deployments in addition to any + # annotations defined for a specific gateway in `terminatingGateways.gateways`. + # Example: + # annotations: | + # "annotation-key": "annotation-value" + annotations: null + + # [Enterprise Only] `consulNamespace` defines the Consul namespace to register + # the gateway into. Requires `global.enableConsulNamespaces` to be true and + # Consul Enterprise v1.7+ with a valid Consul Enterprise license. + # Note: The Consul namespace MUST exist before the gateway is deployed. + consulNamespace: "default" + + # Gateways is a list of gateway objects. The only required field for + # each is `name`, though they can also contain any of the fields in + # `defaults`. Values defined here override the defaults except in the + # case of annotations where both will be applied. + gateways: + - name: terminating-gateway + # Control whether a test Pod manifest is generated when running helm template. # When using helm install, the test Pod is not submitted to the cluster so this # is only useful when running helm template. From 83e48fb9db28e46199d2d4a87afb531fddffe7d9 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 26 May 2020 11:24:00 -0700 Subject: [PATCH 377/739] Fully deprecate global.bootstrapACLs --- templates/NOTES.txt | 2 +- templates/client-clusterrole.yaml | 4 ++-- templates/client-daemonset.yaml | 10 +++++----- .../client-snapshot-agent-clusterrole.yaml | 4 ++-- .../client-snapshot-agent-deployment.yaml | 16 ++++++++-------- .../connect-inject-authmethod-clusterrole.yaml | 2 +- ...t-inject-authmethod-clusterrolebinding.yaml | 2 +- ...nnect-inject-authmethod-serviceaccount.yaml | 2 +- templates/connect-inject-clusterrole.yaml | 2 +- templates/connect-inject-deployment.yaml | 10 +++++----- templates/create-federation-secret-job.yaml | 2 +- templates/create-federation-secret-role.yaml | 2 +- templates/enterprise-license-clusterrole.yaml | 4 ++-- templates/enterprise-license-job.yaml | 4 ++-- templates/ingress-gateways-deployment.yaml | 8 ++++---- templates/ingress-gateways-role.yaml | 2 +- templates/mesh-gateway-clusterrole.yaml | 4 ++-- templates/mesh-gateway-deployment.yaml | 10 +++++----- .../server-acl-init-cleanup-clusterrole.yaml | 2 +- ...er-acl-init-cleanup-clusterrolebinding.yaml | 2 +- templates/server-acl-init-cleanup-job.yaml | 2 +- ...ver-acl-init-cleanup-podsecuritypolicy.yaml | 2 +- ...server-acl-init-cleanup-serviceaccount.yaml | 2 +- templates/server-acl-init-clusterrole.yaml | 2 +- .../server-acl-init-clusterrolebinding.yaml | 2 +- templates/server-acl-init-job.yaml | 5 +++-- .../server-acl-init-podsecuritypolicy.yaml | 2 +- templates/server-acl-init-serviceaccount.yaml | 2 +- templates/server-config-configmap.yaml | 2 +- templates/sync-catalog-clusterrole.yaml | 2 +- templates/sync-catalog-deployment.yaml | 8 ++++---- templates/terminating-gateways-deployment.yaml | 8 ++++---- templates/terminating-gateways-role.yaml | 4 ++-- test/unit/helpers.bats | 18 ------------------ test/unit/server-acl-init-job.bats | 10 ++++++++++ test/unit/sync-catalog-deployment.bats | 1 - values.yaml | 3 --- 37 files changed, 79 insertions(+), 90 deletions(-) diff --git a/templates/NOTES.txt b/templates/NOTES.txt index beb6d943ba..d477664e1d 100644 --- a/templates/NOTES.txt +++ b/templates/NOTES.txt @@ -20,7 +20,7 @@ To learn more about the release if you are using Helm 3, run: $ helm get all {{ .Release.Name }} -{{- if (and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (gt (len .Values.server.extraConfig) 3)) }} +{{- if (and .Values.global.acls.manageSystemACLs (gt (len .Values.server.extraConfig) 3)) }} Warning: Defining server extraConfig potentially disrupts the automatic ACL bootstrapping required settings. This may cause future issues if there are conflicts. diff --git a/templates/client-clusterrole.yaml b/templates/client-clusterrole.yaml index abfc230ef7..d3c0214c8d 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-clusterrole.yaml @@ -8,7 +8,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies) }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies) }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -18,7 +18,7 @@ rules: verbs: - use {{- end }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index 0d83fe865f..a48934c239 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -109,7 +109,7 @@ spec: secretName: {{ .name }} {{- end }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: aclconfig emptyDir: {} {{- end }} @@ -201,7 +201,7 @@ spec: -config-dir=/consul/userconfig/{{ .name }} \ {{- end }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} -config-dir=/consul/aclconfig \ {{- end }} -datacenter={{ .Values.global.datacenter }} \ @@ -241,7 +241,7 @@ spec: readOnly: true mountPath: /consul/userconfig/{{ .name }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: aclconfig mountPath: /consul/aclconfig {{- end }} @@ -305,9 +305,9 @@ spec: {{- toYaml .Values.client.resources | nindent 12 }} {{- end }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} + {{- if (or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} initContainers: - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: client-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/client-snapshot-agent-clusterrole.yaml b/templates/client-snapshot-agent-clusterrole.yaml index 6307da5602..0253cdca08 100644 --- a/templates/client-snapshot-agent-clusterrole.yaml +++ b/templates/client-snapshot-agent-clusterrole.yaml @@ -9,7 +9,7 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies) }} +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies) }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -19,7 +19,7 @@ rules: verbs: - use {{- end }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/client-snapshot-agent-deployment.yaml b/templates/client-snapshot-agent-deployment.yaml index db392e365a..c6d7fd67d1 100644 --- a/templates/client-snapshot-agent-deployment.yaml +++ b/templates/client-snapshot-agent-deployment.yaml @@ -37,7 +37,7 @@ spec: {{- if .Values.client.priorityClassName }} priorityClassName: {{ .Values.client.priorityClassName | quote }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey)) }} volumes: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config @@ -47,7 +47,7 @@ spec: - key: {{ .Values.client.snapshotAgent.configSecret.secretKey }} path: snapshot-config.json {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: aclconfig emptyDir: {} {{- end }} @@ -88,7 +88,7 @@ spec: - name: CONSUL_HTTP_ADDR value: http://$(HOST_IP):8500 {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -108,17 +108,17 @@ spec: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} -config-dir=/consul/config \ {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} -config-dir=/consul/aclconfig \ {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) ) }} volumeMounts: {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - name: snapshot-config readOnly: true mountPath: /consul/config {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: aclconfig mountPath: /consul/aclconfig {{- end }} @@ -136,9 +136,9 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} - {{- if (or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} + {{- if (or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} initContainers: - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: client-snapshot-agent-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/connect-inject-authmethod-clusterrole.yaml b/templates/connect-inject-authmethod-clusterrole.yaml index 0d51693bbc..d0387586d4 100644 --- a/templates/connect-inject-authmethod-clusterrole.yaml +++ b/templates/connect-inject-authmethod-clusterrole.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/connect-inject-authmethod-clusterrolebinding.yaml b/templates/connect-inject-authmethod-clusterrolebinding.yaml index 5edc851897..7c8d96b3a5 100644 --- a/templates/connect-inject-authmethod-clusterrolebinding.yaml +++ b/templates/connect-inject-authmethod-clusterrolebinding.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/connect-inject-authmethod-serviceaccount.yaml b/templates/connect-inject-authmethod-serviceaccount.yaml index 0b3330e091..8ce0b39ef9 100644 --- a/templates/connect-inject-authmethod-serviceaccount.yaml +++ b/templates/connect-inject-authmethod-serviceaccount.yaml @@ -1,5 +1,5 @@ {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 6b809f039f..58783c0833 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -25,7 +25,7 @@ rules: verbs: - use {{- end }} -{{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces }} +{{- if and .Values.global.acls.manageSystemACLs .Values.global.enableConsulNamespaces }} - apiGroups: [""] resources: - secrets diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index aceed19a94..ab66cbfb10 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -57,7 +57,7 @@ spec: secretKeyRef: name: {{ .Values.connectInject.aclInjectToken.secretName }} key: {{ .Values.connectInject.aclInjectToken.secretKey }} - {{- else if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- else if .Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -87,7 +87,7 @@ spec: -listen=:8080 \ {{- if .Values.connectInject.overrideAuthMethodName }} -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ - {{- else if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- else if .Values.global.acls.manageSystemACLs }} -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ {{- end }} {{- if .Values.connectInject.centralConfig.enabled }} @@ -113,7 +113,7 @@ spec: -k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ {{- end }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} -consul-cross-namespace-acl-policy=cross-namespace-policy \ {{- end }} {{- end }} @@ -206,9 +206,9 @@ spec: {{- end }} {{- end }} {{- end }} - {{- if or (and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- if or (and .Values.global.acls.manageSystemACLs .Values.global.enableConsulNamespaces) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: - {{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) .Values.global.enableConsulNamespaces }} + {{- if and .Values.global.acls.manageSystemACLs .Values.global.enableConsulNamespaces }} - name: injector-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/create-federation-secret-job.yaml b/templates/create-federation-secret-job.yaml index fe493edca5..b16d54c117 100644 --- a/templates/create-federation-secret-job.yaml +++ b/templates/create-federation-secret-job.yaml @@ -1,6 +1,6 @@ {{- if .Values.global.federation.createFederationSecret }} {{- if not .Values.global.federation.enabled }}{{ fail "global.federation.enabled must be true when global.federation.createFederationSecret is true" }}{{ end }} -{{- if and (not .Values.global.acls.createReplicationToken) (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }}{{ fail "global.acls.createReplicationToken must be true when global.acls.manageSystemACLs is true because the federation secret must include the replication token" }}{{ end }} +{{- if and (not .Values.global.acls.createReplicationToken) .Values.global.acls.manageSystemACLs }}{{ fail "global.acls.createReplicationToken must be true when global.acls.manageSystemACLs is true because the federation secret must include the replication token" }}{{ end }} apiVersion: batch/v1 kind: Job metadata: diff --git a/templates/create-federation-secret-role.yaml b/templates/create-federation-secret-role.yaml index 04e47bca87..086932a831 100644 --- a/templates/create-federation-secret-role.yaml +++ b/templates/create-federation-secret-role.yaml @@ -28,7 +28,7 @@ rules: - {{ template "consul.fullname" . }}-federation verbs: - update - {{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs }} + {{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-clusterrole.yaml index 57197b3808..8b26f6a662 100644 --- a/templates/enterprise-license-clusterrole.yaml +++ b/templates/enterprise-license-clusterrole.yaml @@ -9,9 +9,9 @@ metadata: chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} -{{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies }} +{{- if or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies }} rules: -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/enterprise-license-job.yaml b/templates/enterprise-license-job.yaml index 0adf38c53a..184be9886d 100644 --- a/templates/enterprise-license-job.yaml +++ b/templates/enterprise-license-job.yaml @@ -65,7 +65,7 @@ spec: - name: CONSUL_CACERT value: /consul/tls/ca/tls.crt {{- end}} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -106,7 +106,7 @@ spec: limits: memory: "50Mi" cpu: "50m" - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} initContainers: - name: ent-license-acl-init image: {{ .Values.global.imageK8S }} diff --git a/templates/ingress-gateways-deployment.yaml b/templates/ingress-gateways-deployment.yaml index d7e3f80185..fdaca2953a 100644 --- a/templates/ingress-gateways-deployment.yaml +++ b/templates/ingress-gateways-deployment.yaml @@ -142,7 +142,7 @@ spec: - "/bin/sh" - "-ec" - | - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" $root }}-{{ .name }}-ingress-gateway-acl-token" \ -k8s-namespace={{ $root.Release.Namespace }} \ @@ -238,7 +238,7 @@ spec: EOF /consul-bin/consul services register \ - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} -token-file=/consul/service/acl-token \ {{- end }} /consul/service/service.hcl @@ -288,7 +288,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -396,7 +396,7 @@ spec: - lifecycle-sidecar - -service-config=/consul/service/service.hcl - -consul-binary=/consul-bin/consul - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} - -token-file=/consul/service/acl-token {{- end }} {{- if (default $defaults.priorityClassName .priorityClassName) }} diff --git a/templates/ingress-gateways-role.yaml b/templates/ingress-gateways-role.yaml index a7e10e2c10..ab211eeed1 100644 --- a/templates/ingress-gateways-role.yaml +++ b/templates/ingress-gateways-role.yaml @@ -32,7 +32,7 @@ rules: verbs: - use {{- end }} -{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} +{{- if $root.Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/mesh-gateway-clusterrole.yaml b/templates/mesh-gateway-clusterrole.yaml index 35ba5ac967..2df2ba5343 100644 --- a/templates/mesh-gateway-clusterrole.yaml +++ b/templates/mesh-gateway-clusterrole.yaml @@ -9,7 +9,7 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: mesh-gateway -{{- if or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} +{{- if or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} rules: {{- if .Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -19,7 +19,7 @@ rules: verbs: - use {{- end }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/mesh-gateway-deployment.yaml b/templates/mesh-gateway-deployment.yaml index 2832eea2f1..27abe9d4d5 100644 --- a/templates/mesh-gateway-deployment.yaml +++ b/templates/mesh-gateway-deployment.yaml @@ -1,7 +1,7 @@ {{- if .Values.meshGateway.enabled }} {{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} {{- if not .Values.client.grpc }}{{ fail "client.grpc must be true" }}{{ end -}} -{{- if and (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.acls.manageSystemACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} +{{- if and .Values.global.acls.manageSystemACLs (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.acls.manageSystemACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} {{- /* The below test checks if clients are disabled (and if so, fails). We use the conditional from other client files and prepend 'not' */ -}} {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled" }}{{ end -}} apiVersion: apps/v1 @@ -125,7 +125,7 @@ spec: - "/bin/sh" - "-ec" - | - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" . }}-mesh-gateway-acl-token" \ -k8s-namespace={{ .Release.Namespace }} \ @@ -196,7 +196,7 @@ spec: EOF /consul-bin/consul services register \ - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} -token-file=/consul/service/acl-token \ {{- end }} /consul/service/service.hcl @@ -259,7 +259,7 @@ spec: fieldRef: fieldPath: spec.nodeName {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -353,7 +353,7 @@ spec: - lifecycle-sidecar - -service-config=/consul/service/service.hcl - -consul-binary=/consul-bin/consul - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - -token-file=/consul/service/acl-token {{- end }} resources: diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-clusterrole.yaml index e11ca88abd..7980783b02 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-clusterrole.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-clusterrolebinding.yaml index 24f0809da2..20a02f7216 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-clusterrolebinding.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/server-acl-init-cleanup-job.yaml b/templates/server-acl-init-cleanup-job.yaml index c540fad576..6d8f33bfce 100644 --- a/templates/server-acl-init-cleanup-job.yaml +++ b/templates/server-acl-init-cleanup-job.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} {{- /* See reason for this in server-acl-init-job.yaml */ -}} {{- if eq (int .Values.server.updatePartition) 0 }} # This job deletes the server-acl-init job once it completes successfully. diff --git a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml index 0f5ac1a0e7..9929a63db9 100644 --- a/templates/server-acl-init-cleanup-podsecuritypolicy.yaml +++ b/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy diff --git a/templates/server-acl-init-cleanup-serviceaccount.yaml b/templates/server-acl-init-cleanup-serviceaccount.yaml index db81edfe3f..a5c39a4e5e 100644 --- a/templates/server-acl-init-cleanup-serviceaccount.yaml +++ b/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-clusterrole.yaml index 3007661caf..4ad642c123 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-clusterrole.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-clusterrolebinding.yaml index ff079b6016..eeefa998c3 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-clusterrolebinding.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 061550dd12..532dcfbba1 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -1,8 +1,9 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if and .Values.global.acls.createReplicationToken (not (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs)) }}{{ fail "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" }}{{ end -}} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if and .Values.global.acls.createReplicationToken (not .Values.global.acls.manageSystemACLs) }}{{ fail "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" }}{{ end -}} +{{- if .Values.global.bootstrapACLs }}{{ fail "global.bootstrapACLs is removed, use global.acls.manageSystemACLs instead" }}{{ end -}} +{{- if .Values.global.acls.manageSystemACLs }} {{- /* We don't render this job when server.updatePartition > 0 because that means a server rollout is in progress and this job won't complete unless the rollout is finished (which won't happen until the partition is 0). diff --git a/templates/server-acl-init-podsecuritypolicy.yaml b/templates/server-acl-init-podsecuritypolicy.yaml index 1a45be2919..12a705f116 100644 --- a/templates/server-acl-init-podsecuritypolicy.yaml +++ b/templates/server-acl-init-podsecuritypolicy.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} {{- if .Values.global.enablePodSecurityPolicies }} apiVersion: policy/v1beta1 kind: PodSecurityPolicy diff --git a/templates/server-acl-init-serviceaccount.yaml b/templates/server-acl-init-serviceaccount.yaml index 3b429ff4cd..0f8e5e817c 100644 --- a/templates/server-acl-init-serviceaccount.yaml +++ b/templates/server-acl-init-serviceaccount.yaml @@ -1,6 +1,6 @@ {{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 87a787c969..7b64e45c2c 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -13,7 +13,7 @@ metadata: data: extra-from-values.json: |- {{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} acl-config.json: |- { "acl": { diff --git a/templates/sync-catalog-clusterrole.yaml b/templates/sync-catalog-clusterrole.yaml index ccec8e65a9..41609f7747 100644 --- a/templates/sync-catalog-clusterrole.yaml +++ b/templates/sync-catalog-clusterrole.yaml @@ -29,7 +29,7 @@ rules: - nodes verbs: - get -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} +{{- if .Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 7ca6fafacd..0879962826 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -68,7 +68,7 @@ spec: name: {{ .Values.syncCatalog.aclSyncToken.secretName }} key: {{ .Values.syncCatalog.aclSyncToken.secretKey }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -152,7 +152,7 @@ spec: -k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ {{- end }} {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} -consul-cross-namespace-acl-policy=cross-namespace-policy \ {{- end }} {{- end }} @@ -180,9 +180,9 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} - {{- if or (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- if or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} initContainers: - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.bootstrapACLs) }} + {{- if .Values.global.acls.manageSystemACLs }} - name: sync-acl-init image: {{ .Values.global.imageK8S }} command: diff --git a/templates/terminating-gateways-deployment.yaml b/templates/terminating-gateways-deployment.yaml index e236ac4fb9..837998189b 100644 --- a/templates/terminating-gateways-deployment.yaml +++ b/templates/terminating-gateways-deployment.yaml @@ -156,7 +156,7 @@ spec: - "/bin/sh" - "-ec" - | - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} consul-k8s acl-init \ -secret-name="{{ template "consul.fullname" $root }}-{{ .name }}-terminating-gateway-acl-token" \ -k8s-namespace={{ $root.Release.Namespace }} \ @@ -185,7 +185,7 @@ spec: EOF /consul-bin/consul services register \ - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} -token-file=/consul/service/acl-token \ {{- end }} /consul/service/service.hcl @@ -239,7 +239,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} - name: CONSUL_HTTP_TOKEN valueFrom: secretKeyRef: @@ -342,7 +342,7 @@ spec: - lifecycle-sidecar - -service-config=/consul/service/service.hcl - -consul-binary=/consul-bin/consul - {{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} + {{- if $root.Values.global.acls.manageSystemACLs }} - -token-file=/consul/service/acl-token {{- end }} {{- if (default $defaults.priorityClassName .priorityClassName) }} diff --git a/templates/terminating-gateways-role.yaml b/templates/terminating-gateways-role.yaml index f381518311..8852ffb90e 100644 --- a/templates/terminating-gateways-role.yaml +++ b/templates/terminating-gateways-role.yaml @@ -16,7 +16,7 @@ metadata: release: {{ $root.Release.Name }} component: terminating-gateway terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} -{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs $root.Values.global.enablePodSecurityPolicies) }} +{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.enablePodSecurityPolicies) }} rules: {{- if $root.Values.global.enablePodSecurityPolicies }} - apiGroups: ["policy"] @@ -26,7 +26,7 @@ rules: verbs: - use {{- end }} -{{- if (or $root.Values.global.acls.manageSystemACLs $root.Values.global.bootstrapACLs) }} +{{- if $root.Values.global.acls.manageSystemACLs }} - apiGroups: [""] resources: - secrets diff --git a/test/unit/helpers.bats b/test/unit/helpers.bats index 3d190fa0b0..0124fee3ca 100644 --- a/test/unit/helpers.bats +++ b/test/unit/helpers.bats @@ -255,21 +255,3 @@ load _helpers [ "${actual}" = "" ] } - -#-------------------------------------------------------------------- -# bootstrapACLs deprecation -# -# Test that every place global.bootstrapACLs is used, global.acls.manageSystemACLs -# is also used. -# If this test is failing, you've used either only global.bootstrapACLs or -# only global.acls.manageSystemACLs instead of using the backwards compatible: -# or global.acls.manageSystemACLs global.bootstrapACLs -@test "helper/bootstrapACLs: used alongside manageSystemACLs" { - cd `chart_dir` - - diff=$(diff <(grep -r '\.Values\.global\.bootstrapACLs' templates/*) <(grep -r -e 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) - [ "$diff" = "" ] - - diff=$(diff <(grep -r '\.Values\.global\.acls\.manageSystemACLs' templates/*) <(grep -r -e 'or [\$root]*\.Values\.global\.acls\.manageSystemACLs [\$root]*\.Values\.global\.bootstrapACLs' templates/*) | tee /dev/stderr) - [ "$diff" = "" ] -} diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 7ade416896..0e83f20e62 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -95,6 +95,16 @@ load _helpers [[ "$output" =~ "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" ]] } +# We removed bootstrapACLs, and now fail in case anyone is still using it. +@test "serverACLInit/Job: fails if global.bootstrapACLs is true" { + cd `chart_dir` + run helm template \ + -x templates/server-acl-init-job.yaml \ + --set 'global.bootstrapACLs=true' . + [ "$status" -eq 1 ] + [[ "$output" =~ "global.bootstrapACLs is removed, use global.acls.manageSystemACLs instead" ]] +} + @test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/sync-catalog-deployment.bats b/test/unit/sync-catalog-deployment.bats index e607d4d8cf..77407d01bf 100755 --- a/test/unit/sync-catalog-deployment.bats +++ b/test/unit/sync-catalog-deployment.bats @@ -389,7 +389,6 @@ load _helpers } #-------------------------------------------------------------------- -# global.bootstrapACLs # global.acls.manageSystemACLs @test "syncCatalog/Deployment: CONSUL_HTTP_TOKEN env variable created when global.acls.manageSystemACLs=true" { diff --git a/values.yaml b/values.yaml index fa84e0d0d3..52925cb127 100644 --- a/values.yaml +++ b/values.yaml @@ -165,9 +165,6 @@ global: # of both the catalog sync and connect injector. enableConsulNamespaces: false - # [DEPRECATED] Use acls.manageSystemACLs instead. - bootstrapACLs: false - # Configure ACLs. acls: From 61419ea18bf2ead0fa321fd99d97b982f08bd256 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 18 Jun 2020 10:26:01 -0700 Subject: [PATCH 378/739] Update ingress gateways with bootstrapACLs removal --- templates/server-acl-init-job.yaml | 2 +- test/unit/server-acl-init-job.bats | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/server-acl-init-job.yaml b/templates/server-acl-init-job.yaml index 532dcfbba1..24cd6197fb 100644 --- a/templates/server-acl-init-job.yaml +++ b/templates/server-acl-init-job.yaml @@ -2,7 +2,7 @@ {{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if and .Values.global.acls.createReplicationToken (not .Values.global.acls.manageSystemACLs) }}{{ fail "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" }}{{ end -}} -{{- if .Values.global.bootstrapACLs }}{{ fail "global.bootstrapACLs is removed, use global.acls.manageSystemACLs instead" }}{{ end -}} +{{- if .Values.global.bootstrapACLs }}{{ fail "global.bootstrapACLs was removed, use global.acls.manageSystemACLs instead" }}{{ end -}} {{- if .Values.global.acls.manageSystemACLs }} {{- /* We don't render this job when server.updatePartition > 0 because that means a server rollout is in progress and this job won't complete unless diff --git a/test/unit/server-acl-init-job.bats b/test/unit/server-acl-init-job.bats index 0e83f20e62..e2b94c8e03 100644 --- a/test/unit/server-acl-init-job.bats +++ b/test/unit/server-acl-init-job.bats @@ -102,7 +102,7 @@ load _helpers -x templates/server-acl-init-job.yaml \ --set 'global.bootstrapACLs=true' . [ "$status" -eq 1 ] - [[ "$output" =~ "global.bootstrapACLs is removed, use global.acls.manageSystemACLs instead" ]] + [[ "$output" =~ "global.bootstrapACLs was removed, use global.acls.manageSystemACLs instead" ]] } @test "serverACLInit/Job: does not set -create-client-token=false when client is enabled (the default)" { From c05d9a51f52c275819c92f78da1287ff29f06c5b Mon Sep 17 00:00:00 2001 From: Iryna Shustava Date: Thu, 18 Jun 2020 11:44:41 -0700 Subject: [PATCH 379/739] Update default Envoy image version and OS (#502) --- test/unit/ingress-gateways-deployment.bats | 2 +- test/unit/mesh-gateway-deployment.bats | 2 +- test/unit/terminating-gateways-deployment.bats | 2 +- values.yaml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit/ingress-gateways-deployment.bats b/test/unit/ingress-gateways-deployment.bats index 5ef46fa7a5..8a8201e9a2 100644 --- a/test/unit/ingress-gateways-deployment.bats +++ b/test/unit/ingress-gateways-deployment.bats @@ -85,7 +85,7 @@ load _helpers --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) - [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] + [ "${actual}" = "envoyproxy/envoy-alpine:v1.14.2" ] } @test "ingressGateways/Deployment: envoy image can be set using the global value" { diff --git a/test/unit/mesh-gateway-deployment.bats b/test/unit/mesh-gateway-deployment.bats index 876cf29221..12055dbeb0 100755 --- a/test/unit/mesh-gateway-deployment.bats +++ b/test/unit/mesh-gateway-deployment.bats @@ -238,7 +238,7 @@ key2: value2' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.spec.containers[0].image' | tee /dev/stderr) - [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] + [ "${actual}" = "envoyproxy/envoy-alpine:v1.14.2" ] } @test "meshGateway/Deployment: envoy image can be set" { diff --git a/test/unit/terminating-gateways-deployment.bats b/test/unit/terminating-gateways-deployment.bats index eab45e606a..2075cc06f3 100644 --- a/test/unit/terminating-gateways-deployment.bats +++ b/test/unit/terminating-gateways-deployment.bats @@ -85,7 +85,7 @@ load _helpers --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -s -r '.[0].spec.template.spec.containers[0].image' | tee /dev/stderr) - [ "${actual}" = "envoyproxy/envoy:v1.13.0" ] + [ "${actual}" = "envoyproxy/envoy-alpine:v1.14.2" ] } @test "terminatingGateways/Deployment: envoy image can be set using the global value" { diff --git a/values.yaml b/values.yaml index 52925cb127..61f79f9e2b 100644 --- a/values.yaml +++ b/values.yaml @@ -57,7 +57,7 @@ global: # imageEnvoy defines the default envoy image to use for ingress and # terminating gateways. - imageEnvoy: "envoyproxy/envoy:v1.13.0" + imageEnvoy: "envoyproxy/envoy-alpine:v1.14.2" # datacenter is the name of the datacenter that the agents should register # as. This can't be changed once the Consul cluster is up and running @@ -1028,7 +1028,7 @@ meshGateway: additionalSpec: null # Envoy image to use. For Consul v1.7+, Envoy version 1.13+ is required. - imageEnvoy: envoyproxy/envoy:v1.13.0 + imageEnvoy: envoyproxy/envoy-alpine:v1.14.2 # If set to true, gateway Pods will run on the host network. hostNetwork: false From e2fb73ca3fa00074ceec26f6b4b15dd860a094ad Mon Sep 17 00:00:00 2001 From: Rebecca Zanzig <16315901+adilyse@users.noreply.github.com> Date: Thu, 18 Jun 2020 12:38:29 -0700 Subject: [PATCH 380/739] Update changelog with ingress and terminating gateway info --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0adad8a197..c18d995c88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ FEATURES: +* Supports deploying Consul [Ingress](https://www.consul.io/docs/connect/ingress_gateway) + and [Terminating](https://www.consul.io/docs/connect/terminating_gateway) Gateways. + Multiple different gateways of each type can be deployed with default values that can + be overridden for specific gateways if desired. Full documentation of the configuration + options can be found in the values file or in the Helm chart documentation + ([Ingress](https://www.consul.io/docs/k8s/helm#v-ingressgateways), + [Terminating](https://www.consul.io/docs/k8s/helm#v-terminatinggateways)). + Requires Consul 1.8.0+. + + Ingress gateways: ([GH-456](https://github.com/hashicorp/consul-helm/pull/456)) + Terminating gateways: ([GH-503](https://github.com/hashicorp/consul-helm/pull/503)) + * Resources are now set on all containers. This enables the chart to be deployed in clusters that have resource quotas set. This also ensures that Consul server and client pods won't be evicted by Kubernetes when nodes reach their From 327ce4f484769f0a7948a0e65462e18d1ec1e1bd Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 18 Jun 2020 15:48:04 -0500 Subject: [PATCH 381/739] update changelog --- CHANGELOG.md | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c18d995c88..2f817409ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +## 0.22.0 (June 18, 2020) + FEATURES: * Supports deploying Consul [Ingress](https://www.consul.io/docs/connect/ingress_gateway) @@ -11,8 +13,8 @@ FEATURES: [Terminating](https://www.consul.io/docs/k8s/helm#v-terminatinggateways)). Requires Consul 1.8.0+. - Ingress gateways: ([GH-456](https://github.com/hashicorp/consul-helm/pull/456)) - Terminating gateways: ([GH-503](https://github.com/hashicorp/consul-helm/pull/503)) + Ingress gateways: [[GH-456](https://github.com/hashicorp/consul-helm/pull/456)], + Terminating gateways: [[GH-503](https://github.com/hashicorp/consul-helm/pull/503)] * Resources are now set on all containers. This enables the chart to be deployed in clusters that have resource quotas set. This also ensures that Consul @@ -20,14 +22,22 @@ FEATURES: resource limits. Resource settings have been made configurable for sync catalog, connect inject - and client snapshot deployments. + and client snapshot deployments and sidecar proxies. [[GH-470](https://github.com/hashicorp/consul-helm/pull/470)] The default settings were chosen based on a cluster with a small workload. For production, we recommend monitoring resource usage and modifying the - defaults according to your usage. + defaults according to your usage. [[GH-466](https://github.com/hashicorp/consul-helm/pull/466)] BREAKING CHANGES: +* It is recommended to use the helm repository to install the helm chart instead of cloning this repo directly. Starting with this release + the master branch may contain breaking changes. + + ```sh + $ helm repo add hashicorp https://helm.releases.hashicorp.com + $ helm install consul hashicorp/consul --set global.name=consul + ``` + * Mesh Gateway: `meshGateway.enableHealthChecks` is no longer supported. This config option was to work around an issue where mesh gateways would not listen on their bind ports until a Connect service was registered. This issue was fixed in Consul 1.6.2. ([GH-464](https://github.com/hashicorp/consul-helm/pull/464)) @@ -59,25 +69,39 @@ BREAKING CHANGES: cpu: "100m" ``` - * Clients and Servers: There are now default resource settings for Consul clients +* Clients and Servers: There are now default resource settings for Consul clients and servers. Previously, there were no default settings which meant the default was unlimited. This change was made because Kubernetes will prefer to evict pods that don't have resource settings and that resulted in the Consul client and servers being evicted. The default resource settings were chosen based on a low-usage cluster. If you are running a production cluster, use the `kubectl top` command to see how much CPU and memory your clients and servers - are using and set the resources accordingly. ([GH-466](https://github.com/hashicorp/consul-helm/pull/466)] + are using and set the resources accordingly [[GH-466](https://github.com/hashicorp/consul-helm/pull/466)]. +* `global.bootstrapACLs` has been removed, use `global.acls.manageSystemACLs` instead [[GH-501](https://github.com/hashicorp/consul-helm/pull/501)]. IMPROVEMENTS: * Add component label to the server, DNS, and UI services [[GH-480](https://github.com/hashicorp/consul-helm/pull/480)]. +* Provide the ability to set a custom CA Cert for consul snapshot agent [[GH-481](https://github.com/hashicorp/consul-helm/pull/481)]. +* Add support for client host networking [[GH-496](https://github.com/hashicorp/consul-helm/pull/496)]. + + To enable: + ```yaml + client: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + ``` +* Add ability to set Affinity and Tolerations to Connect Inject and Catalog Sync [[GH-335](https://github.com/hashicorp/consul-helm/pull/335)]. +* Updated the default consul-k8s version to 0.16.0. +* Updated the default consul version to 1.8.0. +* Update default Envoy image version and OS to `envoyproxy/envoy-alpine:1.14.2` [[GH-502](https://github.com/hashicorp/consul-helm/pull/502)]. DEPRECATIONS * Setting resources via YAML string is now deprecated. Instead, set directly as YAML. This affects `client.resources`, `server.resources` and `meshGateway.resources`. To set directly as YAML, simply remove the pipe (`|`) character that defines - the YAML as a string: + the YAML as a string [[GH-465](https://github.com/hashicorp/consul-helm/pull/465)]: Before: ```yaml From 078bed621c930284f669677ec777e443b0f8d330 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 24 Jun 2020 17:01:39 -0500 Subject: [PATCH 382/739] remove enterprise license cluster roles (#511) * remove unnecessary cluster role usage for enterprise license templates --- ...role.yaml => enterprise-license-role.yaml} | 3 +- ...ml => enterprise-license-rolebinding.yaml} | 6 ++-- ...role.bats => enterprise-license-role.bats} | 32 +++++++++---------- ...ts => enterprise-license-rolebinding.bats} | 20 ++++++------ 4 files changed, 31 insertions(+), 30 deletions(-) rename templates/{enterprise-license-clusterrole.yaml => enterprise-license-role.yaml} (95%) rename templates/{enterprise-license-clusterrolebinding.yaml => enterprise-license-rolebinding.yaml} (90%) rename test/unit/{enterprise-license-clusterrole.bats => enterprise-license-role.bats} (66%) rename test/unit/{enterprise-license-clusterrolebinding.bats => enterprise-license-rolebinding.bats} (60%) diff --git a/templates/enterprise-license-clusterrole.yaml b/templates/enterprise-license-role.yaml similarity index 95% rename from templates/enterprise-license-clusterrole.yaml rename to templates/enterprise-license-role.yaml index 8b26f6a662..ff851a5344 100644 --- a/templates/enterprise-license-clusterrole.yaml +++ b/templates/enterprise-license-role.yaml @@ -1,9 +1,10 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/enterprise-license-clusterrolebinding.yaml b/templates/enterprise-license-rolebinding.yaml similarity index 90% rename from templates/enterprise-license-clusterrolebinding.yaml rename to templates/enterprise-license-rolebinding.yaml index 6469adc372..36c3c14e7e 100644 --- a/templates/enterprise-license-clusterrolebinding.yaml +++ b/templates/enterprise-license-rolebinding.yaml @@ -1,9 +1,10 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -11,11 +12,10 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-enterprise-license subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-enterprise-license - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/test/unit/enterprise-license-clusterrole.bats b/test/unit/enterprise-license-role.bats similarity index 66% rename from test/unit/enterprise-license-clusterrole.bats rename to test/unit/enterprise-license-role.bats index b4ac2f7dd2..0caab2cff3 100644 --- a/test/unit/enterprise-license-clusterrole.bats +++ b/test/unit/enterprise-license-role.bats @@ -2,19 +2,19 @@ load _helpers -@test "enterpriseLicense/ClusterRole: disabled by default" { +@test "enterpriseLicense/Role: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled with server=false, ent secret defined" { +@test "enterpriseLicense/Role: disabled with server=false, ent secret defined" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ @@ -23,30 +23,30 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled when ent secretName missing" { +@test "enterpriseLicense/Role: disabled when ent secretName missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: disabled when ent secretKey missing" { +@test "enterpriseLicense/Role: disabled when ent secretKey missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRole: enabled when ent license defined" { +@test "enterpriseLicense/Role: enabled when ent license defined" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | @@ -54,10 +54,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "enterpriseLicense/ClusterRole: rules are empty if global.acls.manageSystemACLs and global.enablePodSecurityPolicies are false" { +@test "enterpriseLicense/Role: rules are empty if global.acls.manageSystemACLs and global.enablePodSecurityPolicies are false" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | @@ -68,10 +68,10 @@ load _helpers #-------------------------------------------------------------------- # global.acls.manageSystemACLs -@test "enterpriseLicense/ClusterRole: allows acl token when global.acls.manageSystemACLs is true" { +@test "enterpriseLicense/Role: allows acl token when global.acls.manageSystemACLs is true" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.acls.manageSystemACLs=true' \ @@ -84,10 +84,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "enterpriseLicense/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { +@test "enterpriseLicense/Role: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrole.yaml \ + -x templates/enterprise-license-role.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ --set 'global.enablePodSecurityPolicies=true' \ diff --git a/test/unit/enterprise-license-clusterrolebinding.bats b/test/unit/enterprise-license-rolebinding.bats similarity index 60% rename from test/unit/enterprise-license-clusterrolebinding.bats rename to test/unit/enterprise-license-rolebinding.bats index eee9bbf994..c763a872c2 100644 --- a/test/unit/enterprise-license-clusterrolebinding.bats +++ b/test/unit/enterprise-license-rolebinding.bats @@ -2,19 +2,19 @@ load _helpers -@test "enterpriseLicense/ClusterRoleBinding: disabled by default" { +@test "enterpriseLicense/RoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ + -x templates/enterprise-license-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: disabled with server=false, ent secret defined" { +@test "enterpriseLicense/RoleBinding: disabled with server=false, ent secret defined" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ + -x templates/enterprise-license-rolebinding.yaml \ --set 'server.enabled=false' \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ @@ -23,30 +23,30 @@ load _helpers [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: disabled when ent secretName missing" { +@test "enterpriseLicense/RoleBinding: disabled when ent secretName missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ + -x templates/enterprise-license-rolebinding.yaml \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: disabled when ent secretKey missing" { +@test "enterpriseLicense/RoleBinding: disabled when ent secretKey missing" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ + -x templates/enterprise-license-rolebinding.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "enterpriseLicense/ClusterRoleBinding: enabled when ent license defined" { +@test "enterpriseLicense/RoleBinding: enabled when ent license defined" { cd `chart_dir` local actual=$(helm template \ - -x templates/enterprise-license-clusterrolebinding.yaml \ + -x templates/enterprise-license-rolebinding.yaml \ --set 'server.enterpriseLicense.secretName=foo' \ --set 'server.enterpriseLicense.secretKey=bar' \ . | tee /dev/stderr | From fddff4dbb8895f55936e7616460afc4a4c3a762d Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Wed, 24 Jun 2020 17:12:41 -0500 Subject: [PATCH 383/739] remove unnecessary server ClusterRoles (#506) * remove unnecessary server clusterRole/Bindings and add namespace to metadata --- ...yaml => server-acl-init-cleanup-role.yaml} | 3 +- ... server-acl-init-cleanup-rolebinding.yaml} | 6 ++-- ...terrole.yaml => server-acl-init-role.yaml} | 3 +- ....yaml => server-acl-init-rolebinding.yaml} | 6 ++-- ...rver-clusterrole.yaml => server-role.yaml} | 3 +- ...lebinding.yaml => server-rolebinding.yaml} | 6 ++-- ...bats => server-acl-init-cleanup-role.bats} | 24 ++++++++-------- ... server-acl-init-cleanup-rolebinding.bats} | 20 ++++++------- ...terrole.bats => server-acl-init-role.bats} | 28 +++++++++---------- ....bats => server-acl-init-rolebinding.bats} | 20 ++++++------- ...rver-clusterrole.bats => server-role.bats} | 28 +++++++++---------- ...lebinding.bats => server-rolebinding.bats} | 22 +++++++-------- 12 files changed, 86 insertions(+), 83 deletions(-) rename templates/{server-acl-init-cleanup-clusterrole.yaml => server-acl-init-cleanup-role.yaml} (94%) rename templates/{server-acl-init-cleanup-clusterrolebinding.yaml => server-acl-init-cleanup-rolebinding.yaml} (90%) rename templates/{server-acl-init-clusterrole.yaml => server-acl-init-role.yaml} (95%) rename templates/{server-acl-init-clusterrolebinding.yaml => server-acl-init-rolebinding.yaml} (90%) rename templates/{server-clusterrole.yaml => server-role.yaml} (93%) rename templates/{server-clusterrolebinding.yaml => server-rolebinding.yaml} (87%) rename test/unit/{server-acl-init-cleanup-clusterrole.bats => server-acl-init-cleanup-role.bats} (60%) rename test/unit/{server-acl-init-clusterrolebinding.bats => server-acl-init-cleanup-rolebinding.bats} (68%) rename test/unit/{server-acl-init-clusterrole.bats => server-acl-init-role.bats} (64%) rename test/unit/{server-acl-init-cleanup-clusterrolebinding.bats => server-acl-init-rolebinding.bats} (56%) rename test/unit/{server-clusterrole.bats => server-role.bats} (66%) rename test/unit/{server-clusterrolebinding.bats => server-rolebinding.bats} (61%) diff --git a/templates/server-acl-init-cleanup-clusterrole.yaml b/templates/server-acl-init-cleanup-role.yaml similarity index 94% rename from templates/server-acl-init-cleanup-clusterrole.yaml rename to templates/server-acl-init-cleanup-role.yaml index 7980783b02..8d2e3d03b3 100644 --- a/templates/server-acl-init-cleanup-clusterrole.yaml +++ b/templates/server-acl-init-cleanup-role.yaml @@ -2,9 +2,10 @@ {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-acl-init-cleanup-clusterrolebinding.yaml b/templates/server-acl-init-cleanup-rolebinding.yaml similarity index 90% rename from templates/server-acl-init-cleanup-clusterrolebinding.yaml rename to templates/server-acl-init-cleanup-rolebinding.yaml index 20a02f7216..d2e61807d2 100644 --- a/templates/server-acl-init-cleanup-clusterrolebinding.yaml +++ b/templates/server-acl-init-cleanup-rolebinding.yaml @@ -2,9 +2,10 @@ {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -12,11 +13,10 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-server-acl-init-cleanup subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-server-acl-init-cleanup - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/templates/server-acl-init-clusterrole.yaml b/templates/server-acl-init-role.yaml similarity index 95% rename from templates/server-acl-init-clusterrole.yaml rename to templates/server-acl-init-role.yaml index 4ad642c123..4f22d47b7f 100644 --- a/templates/server-acl-init-clusterrole.yaml +++ b/templates/server-acl-init-role.yaml @@ -2,9 +2,10 @@ {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-acl-init-clusterrolebinding.yaml b/templates/server-acl-init-rolebinding.yaml similarity index 90% rename from templates/server-acl-init-clusterrolebinding.yaml rename to templates/server-acl-init-rolebinding.yaml index eeefa998c3..2c54452603 100644 --- a/templates/server-acl-init-clusterrolebinding.yaml +++ b/templates/server-acl-init-rolebinding.yaml @@ -2,9 +2,10 @@ {{- if (or $serverEnabled .Values.externalServers.enabled) }} {{- if .Values.global.acls.manageSystemACLs }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -12,11 +13,10 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-server-acl-init subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-server-acl-init - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/templates/server-clusterrole.yaml b/templates/server-role.yaml similarity index 93% rename from templates/server-clusterrole.yaml rename to templates/server-role.yaml index e58d964f74..85f4d54839 100644 --- a/templates/server-clusterrole.yaml +++ b/templates/server-role.yaml @@ -1,8 +1,9 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/server-clusterrolebinding.yaml b/templates/server-rolebinding.yaml similarity index 87% rename from templates/server-clusterrolebinding.yaml rename to templates/server-rolebinding.yaml index b81f8c387d..788fc978f7 100644 --- a/templates/server-clusterrolebinding.yaml +++ b/templates/server-rolebinding.yaml @@ -1,8 +1,9 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -10,10 +11,9 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-server subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-server - namespace: {{ .Release.Namespace }} {{- end }} diff --git a/test/unit/server-acl-init-cleanup-clusterrole.bats b/test/unit/server-acl-init-cleanup-role.bats similarity index 60% rename from test/unit/server-acl-init-cleanup-clusterrole.bats rename to test/unit/server-acl-init-cleanup-role.bats index 7b82bae808..0c26dab05e 100644 --- a/test/unit/server-acl-init-cleanup-clusterrole.bats +++ b/test/unit/server-acl-init-cleanup-role.bats @@ -2,29 +2,29 @@ load _helpers -@test "serverACLInitCleanup/ClusterRole: disabled by default" { +@test "serverACLInitCleanup/Role: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRole: enabled with global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/Role: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRole: disabled with server=false and global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/Role: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -32,10 +32,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRole: enabled with client=true and global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/Role: enabled with client=true and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=true' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRole: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { +@test "serverACLInitCleanup/Role: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ @@ -59,10 +59,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "serverACLInitCleanup/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { +@test "serverACLInitCleanup/Role: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrole.yaml \ + -x templates/server-acl-init-cleanup-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | diff --git a/test/unit/server-acl-init-clusterrolebinding.bats b/test/unit/server-acl-init-cleanup-rolebinding.bats similarity index 68% rename from test/unit/server-acl-init-clusterrolebinding.bats rename to test/unit/server-acl-init-cleanup-rolebinding.bats index fe833ef2b8..b1c6107ea9 100644 --- a/test/unit/server-acl-init-clusterrolebinding.bats +++ b/test/unit/server-acl-init-cleanup-rolebinding.bats @@ -2,29 +2,29 @@ load _helpers -@test "serverACLInit/ClusterRoleBinding: disabled by default" { +@test "serverACLInitCleanup/RoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ + -x templates/server-acl-init-cleanup-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/RoleBinding: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ + -x templates/server-acl-init-cleanup-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/RoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ + -x templates/server-acl-init-cleanup-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -32,10 +32,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { +@test "serverACLInitCleanup/RoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ + -x templates/server-acl-init-cleanup-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { +@test "serverACLInitCleanup/RoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrolebinding.yaml \ + -x templates/server-acl-init-cleanup-rolebinding.yaml \ --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ diff --git a/test/unit/server-acl-init-clusterrole.bats b/test/unit/server-acl-init-role.bats similarity index 64% rename from test/unit/server-acl-init-clusterrole.bats rename to test/unit/server-acl-init-role.bats index 01bf3f0197..39d480a7f4 100644 --- a/test/unit/server-acl-init-clusterrole.bats +++ b/test/unit/server-acl-init-role.bats @@ -2,29 +2,29 @@ load _helpers -@test "serverACLInit/ClusterRole: disabled by default" { +@test "serverACLInit/Role: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: enabled with global.acls.manageSystemACLs=true" { +@test "serverACLInit/Role: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRole: disabled with server=false and global.acls.manageSystemACLs=true" { +@test "serverACLInit/Role: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -32,10 +32,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInit/ClusterRole: enabled with client=false and global.acls.manageSystemACLs=true" { +@test "serverACLInit/Role: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInit/ClusterRole: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { +@test "serverACLInit/Role: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ @@ -59,10 +59,10 @@ load _helpers #-------------------------------------------------------------------- # connectInject.enabled -@test "serverACLInit/ClusterRole: allows service accounts when connectInject.enabled is true" { +@test "serverACLInit/Role: allows service accounts when connectInject.enabled is true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'connectInject.enabled=true' \ . | tee /dev/stderr | @@ -73,10 +73,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "serverACLInit/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { +@test "serverACLInit/Role: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-clusterrole.yaml \ + -x templates/server-acl-init-role.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | diff --git a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats b/test/unit/server-acl-init-rolebinding.bats similarity index 56% rename from test/unit/server-acl-init-cleanup-clusterrolebinding.bats rename to test/unit/server-acl-init-rolebinding.bats index ff4821ea26..e997036364 100644 --- a/test/unit/server-acl-init-cleanup-clusterrolebinding.bats +++ b/test/unit/server-acl-init-rolebinding.bats @@ -2,29 +2,29 @@ load _helpers -@test "serverACLInitCleanup/ClusterRoleBinding: disabled by default" { +@test "serverACLInit/RoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + -x templates/server-acl-init-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: enabled with global.acls.manageSystemACLs=true" { +@test "serverACLInit/RoleBinding: enabled with global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + -x templates/server-acl-init-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { +@test "serverACLInit/RoleBinding: disabled with server=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + -x templates/server-acl-init-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -32,10 +32,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { +@test "serverACLInit/RoleBinding: enabled with client=false and global.acls.manageSystemACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + -x templates/server-acl-init-rolebinding.yaml \ --set 'global.acls.manageSystemACLs=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "serverACLInitCleanup/ClusterRoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { +@test "serverACLInit/RoleBinding: enabled with externalServers.enabled=true and global.acls.manageSystemACLs=true, but server.enabled set to false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-acl-init-cleanup-clusterrolebinding.yaml \ + -x templates/server-acl-init-rolebinding.yaml \ --set 'server.enabled=false' \ --set 'global.acls.manageSystemACLs=true' \ --set 'externalServers.enabled=true' \ diff --git a/test/unit/server-clusterrole.bats b/test/unit/server-role.bats similarity index 66% rename from test/unit/server-clusterrole.bats rename to test/unit/server-role.bats index 88f005bc65..ebcf6d6bd7 100644 --- a/test/unit/server-clusterrole.bats +++ b/test/unit/server-role.bats @@ -2,29 +2,29 @@ load _helpers -@test "server/ClusterRole: enabled by default" { +@test "server/Role: enabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "server/ClusterRole: disabled with global.enabled=false" { +@test "server/Role: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "server/ClusterRole: can be enabled with global.enabled=false" { +@test "server/Role: can be enabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'global.enabled=false' \ --set 'server.enabled=true' \ . | tee /dev/stderr | @@ -32,20 +32,20 @@ load _helpers [ "${actual}" = "true" ] } -@test "server/ClusterRole: disabled with server.enabled=false" { +@test "server/Role: disabled with server.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "server/ClusterRole: enabled with server.enabled=true" { +@test "server/Role: enabled with server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'server.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -53,10 +53,10 @@ load _helpers } # The rules key must always be set (#178). -@test "server/ClusterRole: rules empty with server.enabled=true" { +@test "server/Role: rules empty with server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'server.enabled=true' \ . | tee /dev/stderr | yq '.rules' | tee /dev/stderr) @@ -66,10 +66,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "server/ClusterRole: podsecuritypolicies are added when global.enablePodSecurityPolicies is true" { +@test "server/Role: podsecuritypolicies are added when global.enablePodSecurityPolicies is true" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrole.yaml \ + -x templates/server-role.yaml \ --set 'server.enabled=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | diff --git a/test/unit/server-clusterrolebinding.bats b/test/unit/server-rolebinding.bats similarity index 61% rename from test/unit/server-clusterrolebinding.bats rename to test/unit/server-rolebinding.bats index 125b767ed4..673b45f6f0 100644 --- a/test/unit/server-clusterrolebinding.bats +++ b/test/unit/server-rolebinding.bats @@ -2,52 +2,52 @@ load _helpers -@test "server/ClusterRoleBinding: enabled by default" { +@test "server/RoleBinding: enabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrolebinding.yaml \ + -x templates/server-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "server/ClusterRoleBinding: disabled with global.enabled=false" { +@test "server/RoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrolebinding.yaml \ + -x templates/server-rolebinding.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "server/ClusterRoleBinding: disabled with server disabled" { +@test "server/RoleBinding: disabled with server disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrolebinding.yaml \ + -x templates/server-rolebinding.yaml \ --set 'server.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "server/ClusterRoleBinding: enabled with server enabled" { +@test "server/RoleBinding: enabled with server enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrolebinding.yaml \ + -x templates/server-rolebinding.yaml \ --set 'server.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "server/ClusterRoleBinding: enabled with server enabled and global.enabled=false" { +@test "server/RoleBinding: enabled with server enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/server-clusterrolebinding.yaml \ + -x templates/server-rolebinding.yaml \ --set 'global.enabled=false' \ --set 'server.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] -} \ No newline at end of file +} From e73557c0d46e62a4b127d7e73ec2c9a2ac218c70 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 25 Jun 2020 09:56:53 -0500 Subject: [PATCH 384/739] Remove unnecessary client ClusterRoles (#505) * Client templates to use rolebindings instead of clusterrolebindings --- ...ient-clusterrole.yaml => client-role.yaml} | 3 +- ...lebinding.yaml => client-rolebinding.yaml} | 6 ++-- ...e.yaml => client-snapshot-agent-role.yaml} | 3 +- ...=> client-snapshot-agent-rolebinding.yaml} | 6 ++-- ...ient-clusterrole.bats => client-role.bats} | 36 +++++++++---------- ...lebinding.bats => client-rolebinding.bats} | 22 ++++++------ ...e.bats => client-snapshot-agent-role.bats} | 28 +++++++-------- ...=> client-snapshot-agent-rolebinding.bats} | 18 +++++----- 8 files changed, 62 insertions(+), 60 deletions(-) rename templates/{client-clusterrole.yaml => client-role.yaml} (95%) rename templates/{client-clusterrolebinding.yaml => client-rolebinding.yaml} (87%) rename templates/{client-snapshot-agent-clusterrole.yaml => client-snapshot-agent-role.yaml} (95%) rename templates/{client-snapshot-agent-clusterrolebinding.yaml => client-snapshot-agent-rolebinding.yaml} (89%) rename test/unit/{client-clusterrole.bats => client-role.bats} (66%) rename test/unit/{client-clusterrolebinding.bats => client-rolebinding.bats} (61%) rename test/unit/{client-snapshot-agent-clusterrole.bats => client-snapshot-agent-role.bats} (63%) rename test/unit/{client-snapshot-agent-clusterrolebinding.bats => client-snapshot-agent-rolebinding.bats} (55%) diff --git a/templates/client-clusterrole.yaml b/templates/client-role.yaml similarity index 95% rename from templates/client-clusterrole.yaml rename to templates/client-role.yaml index d3c0214c8d..5a9f90ef2f 100644 --- a/templates/client-clusterrole.yaml +++ b/templates/client-role.yaml @@ -1,8 +1,9 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/client-clusterrolebinding.yaml b/templates/client-rolebinding.yaml similarity index 87% rename from templates/client-clusterrolebinding.yaml rename to templates/client-rolebinding.yaml index d769b24504..25681c6e14 100644 --- a/templates/client-clusterrolebinding.yaml +++ b/templates/client-rolebinding.yaml @@ -1,8 +1,9 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -10,10 +11,9 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-client subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-client - namespace: {{ .Release.Namespace }} {{- end }} diff --git a/templates/client-snapshot-agent-clusterrole.yaml b/templates/client-snapshot-agent-role.yaml similarity index 95% rename from templates/client-snapshot-agent-clusterrole.yaml rename to templates/client-snapshot-agent-role.yaml index 0253cdca08..07781430c7 100644 --- a/templates/client-snapshot-agent-clusterrole.yaml +++ b/templates/client-snapshot-agent-role.yaml @@ -1,9 +1,10 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.client.snapshotAgent.enabled }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-snapshot-agent + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/templates/client-snapshot-agent-clusterrolebinding.yaml b/templates/client-snapshot-agent-rolebinding.yaml similarity index 89% rename from templates/client-snapshot-agent-clusterrolebinding.yaml rename to templates/client-snapshot-agent-rolebinding.yaml index b4a27555aa..bc5d9e72b2 100644 --- a/templates/client-snapshot-agent-clusterrolebinding.yaml +++ b/templates/client-snapshot-agent-rolebinding.yaml @@ -1,9 +1,10 @@ {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.client.snapshotAgent.enabled }} apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-snapshot-agent + namespace: {{ .Release.Namespace }} labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} @@ -11,11 +12,10 @@ metadata: release: {{ .Release.Name }} roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-snapshot-agent subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-snapshot-agent - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/test/unit/client-clusterrole.bats b/test/unit/client-role.bats similarity index 66% rename from test/unit/client-clusterrole.bats rename to test/unit/client-role.bats index 1a7e95d377..acad5cd819 100644 --- a/test/unit/client-clusterrole.bats +++ b/test/unit/client-role.bats @@ -2,29 +2,29 @@ load _helpers -@test "client/ClusterRole: enabled by default" { +@test "client/Role: enabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/ClusterRole: disabled with global.enabled=false" { +@test "client/Role: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/ClusterRole: can be enabled with global.enabled=false" { +@test "client/Role: can be enabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'global.enabled=false' \ --set 'client.enabled=true' \ . | tee /dev/stderr | @@ -32,20 +32,20 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/ClusterRole: disabled with client.enabled=false" { +@test "client/Role: disabled with client.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/ClusterRole: enabled with client.enabled=true" { +@test "client/Role: enabled with client.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) @@ -53,10 +53,10 @@ load _helpers } # The rules key must always be set (#178). -@test "client/ClusterRole: rules empty with client.enabled=true" { +@test "client/Role: rules empty with client.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=true' \ . | tee /dev/stderr | yq '.rules' | tee /dev/stderr) @@ -66,10 +66,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "client/ClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { +@test "client/Role: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | @@ -80,10 +80,10 @@ load _helpers #-------------------------------------------------------------------- # global.acls.manageSystemACLs -@test "client/ClusterRole: allows secret access with global.bootsrapACLs=true" { +@test "client/Role: allows secret access with global.bootsrapACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=true' \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | @@ -91,10 +91,10 @@ load _helpers [ "${actual}" = "secrets" ] } -@test "client/ClusterRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { +@test "client/Role: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrole.yaml \ + -x templates/client-role.yaml \ --set 'client.enabled=true' \ --set 'global.acls.manageSystemACLs=true' \ --set 'global.enablePodSecurityPolicies=true' \ diff --git a/test/unit/client-clusterrolebinding.bats b/test/unit/client-rolebinding.bats similarity index 61% rename from test/unit/client-clusterrolebinding.bats rename to test/unit/client-rolebinding.bats index 31bd33f77a..c19dde1900 100644 --- a/test/unit/client-clusterrolebinding.bats +++ b/test/unit/client-rolebinding.bats @@ -2,52 +2,52 @@ load _helpers -@test "client/ClusterRoleBinding: enabled by default" { +@test "client/RoleBinding: enabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrolebinding.yaml \ + -x templates/client-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/ClusterRoleBinding: disabled with global.enabled=false" { +@test "client/RoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrolebinding.yaml \ + -x templates/client-rolebinding.yaml \ --set 'global.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/ClusterRoleBinding: disabled with client disabled" { +@test "client/RoleBinding: disabled with client disabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrolebinding.yaml \ + -x templates/client-rolebinding.yaml \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/ClusterRoleBinding: enabled with client enabled" { +@test "client/RoleBinding: enabled with client enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrolebinding.yaml \ + -x templates/client-rolebinding.yaml \ --set 'client.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/ClusterRoleBinding: enabled with client enabled and global.enabled=false" { +@test "client/RoleBinding: enabled with client enabled and global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-clusterrolebinding.yaml \ + -x templates/client-rolebinding.yaml \ --set 'global.enabled=false' \ --set 'client.enabled=true' \ . | tee /dev/stderr | yq -s 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] -} \ No newline at end of file +} diff --git a/test/unit/client-snapshot-agent-clusterrole.bats b/test/unit/client-snapshot-agent-role.bats similarity index 63% rename from test/unit/client-snapshot-agent-clusterrole.bats rename to test/unit/client-snapshot-agent-role.bats index 72613eaa61..4af3e05dbb 100644 --- a/test/unit/client-snapshot-agent-clusterrole.bats +++ b/test/unit/client-snapshot-agent-role.bats @@ -2,29 +2,29 @@ load _helpers -@test "client/SnapshotAgentClusterRole: disabled by default" { +@test "client/SnapshotAgentRole: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/SnapshotAgentClusterRole: enabled with client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRole: enabled with client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/SnapshotAgentClusterRole: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRole: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.enabled=true' \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | @@ -32,10 +32,10 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/SnapshotAgentClusterRole: disabled with client=false and client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRole: disabled with client=false and client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | @@ -46,10 +46,10 @@ load _helpers #-------------------------------------------------------------------- # global.enablePodSecurityPolicies -@test "client/SnapshotAgentClusterRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { +@test "client/SnapshotAgentRole: allows podsecuritypolicies access with global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'client.enabled=true' \ --set 'global.enablePodSecurityPolicies=true' \ @@ -61,10 +61,10 @@ load _helpers #-------------------------------------------------------------------- # global.acls.manageSystemACLs -@test "client/SnapshotAgentClusterRole: allows secret access with global.bootsrapACLs=true" { +@test "client/SnapshotAgentRole: allows secret access with global.bootsrapACLs=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'client.enabled=true' \ --set 'global.acls.manageSystemACLs=true' \ @@ -73,10 +73,10 @@ load _helpers [ "${actual}" = "secrets" ] } -@test "client/SnapshotAgentClusterRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { +@test "client/SnapshotAgentRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrole.yaml \ + -x templates/client-snapshot-agent-role.yaml \ --set 'client.enabled=true' \ --set 'client.snapshotAgent.enabled=true' \ --set 'global.acls.manageSystemACLs=true' \ diff --git a/test/unit/client-snapshot-agent-clusterrolebinding.bats b/test/unit/client-snapshot-agent-rolebinding.bats similarity index 55% rename from test/unit/client-snapshot-agent-clusterrolebinding.bats rename to test/unit/client-snapshot-agent-rolebinding.bats index 887d695872..2ae01e2d05 100644 --- a/test/unit/client-snapshot-agent-clusterrolebinding.bats +++ b/test/unit/client-snapshot-agent-rolebinding.bats @@ -2,29 +2,29 @@ load _helpers -@test "client/SnapshotAgentClusterRoleBinding: disabled by default" { +@test "client/SnapshotAgentRoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + -x templates/client-snapshot-agent-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "client/SnapshotAgentClusterRoleBinding: enabled with client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRoleBinding: enabled with client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + -x templates/client-snapshot-agent-rolebinding.yaml \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/SnapshotAgentClusterRoleBinding: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRoleBinding: enabled with client.enabled=true and client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + -x templates/client-snapshot-agent-rolebinding.yaml \ --set 'client.enabled=true' \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | @@ -32,13 +32,13 @@ load _helpers [ "${actual}" = "true" ] } -@test "client/SnapshotAgentClusterRoleBinding: disabled with client=false and client.snapshotAgent.enabled=true" { +@test "client/SnapshotAgentRoleBinding: disabled with client=false and client.snapshotAgent.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/client-snapshot-agent-clusterrolebinding.yaml \ + -x templates/client-snapshot-agent-rolebinding.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'client.enabled=false' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] -} \ No newline at end of file +} From 685c6d5435e510e8e56aafe7ba25a05dece394c5 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 25 Jun 2020 10:22:21 -0500 Subject: [PATCH 385/739] Do not use ClusterRole/Bindings unnecessarily for tls-init templates (#498) * Use Role/Binding instead of ClusterRole/Binding for tls-init templates --- ...errole.yaml => tls-init-cleanup-role.yaml} | 2 +- ...yaml => tls-init-cleanup-rolebinding.yaml} | 5 ++-- ...it-clusterrole.yaml => tls-init-role.yaml} | 2 +- ...binding.yaml => tls-init-rolebinding.yaml} | 5 ++-- ...errole.bats => tls-init-cleanup-role.bats} | 26 +++++++++---------- ...bats => tls-init-cleanup-rolebinding.bats} | 20 +++++++------- ...up-clusterrole.bats => tls-init-role.bats} | 26 +++++++++---------- ...binding.bats => tls-init-rolebinding.bats} | 20 +++++++------- 8 files changed, 52 insertions(+), 54 deletions(-) rename templates/{tls-init-cleanup-clusterrole.yaml => tls-init-cleanup-role.yaml} (98%) rename templates/{tls-init-cleanup-clusterrolebinding.yaml => tls-init-cleanup-rolebinding.yaml} (90%) rename templates/{tls-init-clusterrole.yaml => tls-init-role.yaml} (98%) rename templates/{tls-init-clusterrolebinding.yaml => tls-init-rolebinding.yaml} (90%) rename test/unit/{tls-init-clusterrole.bats => tls-init-cleanup-role.bats} (66%) rename test/unit/{tls-init-clusterrolebinding.bats => tls-init-cleanup-rolebinding.bats} (65%) rename test/unit/{tls-init-cleanup-clusterrole.bats => tls-init-role.bats} (59%) rename test/unit/{tls-init-cleanup-clusterrolebinding.bats => tls-init-rolebinding.bats} (59%) diff --git a/templates/tls-init-cleanup-clusterrole.yaml b/templates/tls-init-cleanup-role.yaml similarity index 98% rename from templates/tls-init-cleanup-clusterrole.yaml rename to templates/tls-init-cleanup-role.yaml index 7458f4e45e..c6f8605eac 100644 --- a/templates/tls-init-cleanup-clusterrole.yaml +++ b/templates/tls-init-cleanup-role.yaml @@ -1,7 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-tls-init-cleanup namespace: {{ .Release.Namespace }} diff --git a/templates/tls-init-cleanup-clusterrolebinding.yaml b/templates/tls-init-cleanup-rolebinding.yaml similarity index 90% rename from templates/tls-init-cleanup-clusterrolebinding.yaml rename to templates/tls-init-cleanup-rolebinding.yaml index c8b14ab24e..8144c98d92 100644 --- a/templates/tls-init-cleanup-clusterrolebinding.yaml +++ b/templates/tls-init-cleanup-rolebinding.yaml @@ -1,7 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-tls-init-cleanup namespace: {{ .Release.Namespace }} @@ -15,11 +15,10 @@ metadata: "helm.sh/hook-delete-policy": hook-succeeded roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-tls-init-cleanup subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-tls-init-cleanup - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/templates/tls-init-clusterrole.yaml b/templates/tls-init-role.yaml similarity index 98% rename from templates/tls-init-clusterrole.yaml rename to templates/tls-init-role.yaml index dfd75eb04a..1541ec364c 100644 --- a/templates/tls-init-clusterrole.yaml +++ b/templates/tls-init-role.yaml @@ -1,7 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole +kind: Role metadata: name: {{ template "consul.fullname" . }}-tls-init namespace: {{ .Release.Namespace }} diff --git a/templates/tls-init-clusterrolebinding.yaml b/templates/tls-init-rolebinding.yaml similarity index 90% rename from templates/tls-init-clusterrolebinding.yaml rename to templates/tls-init-rolebinding.yaml index 7ce6801fa2..fe237ef0f9 100644 --- a/templates/tls-init-clusterrolebinding.yaml +++ b/templates/tls-init-rolebinding.yaml @@ -1,7 +1,7 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding +kind: RoleBinding metadata: name: {{ template "consul.fullname" . }}-tls-init namespace: {{ .Release.Namespace }} @@ -15,11 +15,10 @@ metadata: "helm.sh/hook-delete-policy": before-hook-creation roleRef: apiGroup: rbac.authorization.k8s.io - kind: ClusterRole + kind: Role name: {{ template "consul.fullname" . }}-tls-init subjects: - kind: ServiceAccount name: {{ template "consul.fullname" . }}-tls-init - namespace: {{ .Release.Namespace }} {{- end }} {{- end }} diff --git a/test/unit/tls-init-clusterrole.bats b/test/unit/tls-init-cleanup-role.bats similarity index 66% rename from test/unit/tls-init-clusterrole.bats rename to test/unit/tls-init-cleanup-role.bats index b842e97c0d..820e6ff74f 100644 --- a/test/unit/tls-init-clusterrole.bats +++ b/test/unit/tls-init-cleanup-role.bats @@ -2,19 +2,19 @@ load _helpers -@test "tlsInit/ClusterRole: disabled by default" { +@test "tlsInitCleanup/Role: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRole: disabled with global.enabled=false" { +@test "tlsInitCleanup/Role: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enabled=false' \ . | tee /dev/stderr | @@ -22,10 +22,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRole: disabled when server.enabled=false" { +@test "tlsInitCleanup/Role: disabled when server.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -33,10 +33,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRole: enabled when global.tls.enabled=true and server.enabled=true" { +@test "tlsInitCleanup/Role: enabled when global.tls.enabled=true and server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=true' \ . | tee /dev/stderr | @@ -44,24 +44,24 @@ load _helpers [ "${actual}" = "true" ] } -@test "tlsInit/ClusterRole: enabled with global.tls.enabled" { +@test "tlsInitCleanup/Role: enabled with global.tls.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "tlsInit/ClusterRole: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { +@test "tlsInitCleanup/Role: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrole.yaml \ + -x templates/tls-init-cleanup-role.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules[] | select(.resources==["podsecuritypolicies"]) | .resourceNames[0]' | tee /dev/stderr) - [ "${actual}" = "release-name-consul-tls-init" ] + [ "${actual}" = "release-name-consul-tls-init-cleanup" ] } diff --git a/test/unit/tls-init-clusterrolebinding.bats b/test/unit/tls-init-cleanup-rolebinding.bats similarity index 65% rename from test/unit/tls-init-clusterrolebinding.bats rename to test/unit/tls-init-cleanup-rolebinding.bats index b9e5478ebb..f9f664af79 100644 --- a/test/unit/tls-init-clusterrolebinding.bats +++ b/test/unit/tls-init-cleanup-rolebinding.bats @@ -2,19 +2,19 @@ load _helpers -@test "tlsInit/ClusterRoleBinding: disabled by default" { +@test "tlsInitCleanup/RoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrolebinding.yaml \ + -x templates/tls-init-cleanup-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRoleBinding: disabled with global.enabled=false" { +@test "tlsInitCleanup/RoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrolebinding.yaml \ + -x templates/tls-init-cleanup-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enabled=false' \ . | tee /dev/stderr | @@ -22,20 +22,20 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRoleBinding: enabled with global.tls.enabled" { +@test "tlsInitCleanup/RoleBinding: enabled with global.tls.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrolebinding.yaml \ + -x templates/tls-init-cleanup-rolebinding.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "tlsInit/ClusterRoleBinding: disabled when server.enabled=false" { +@test "tlsInitCleanup/RoleBinding: disabled when server.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrolebinding.yaml \ + -x templates/tls-init-cleanup-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInit/ClusterRoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { +@test "tlsInitCleanup/RoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-clusterrolebinding.yaml \ + -x templates/tls-init-cleanup-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=true' \ . | tee /dev/stderr | diff --git a/test/unit/tls-init-cleanup-clusterrole.bats b/test/unit/tls-init-role.bats similarity index 59% rename from test/unit/tls-init-cleanup-clusterrole.bats rename to test/unit/tls-init-role.bats index 0357287971..2fedee4d3f 100644 --- a/test/unit/tls-init-cleanup-clusterrole.bats +++ b/test/unit/tls-init-role.bats @@ -2,19 +2,19 @@ load _helpers -@test "tlsInitCleanup/ClusterRole: disabled by default" { +@test "tlsInit/Role: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRole: disabled with global.enabled=false" { +@test "tlsInit/Role: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enabled=false' \ . | tee /dev/stderr | @@ -22,10 +22,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRole: disabled when server.enabled=false" { +@test "tlsInit/Role: disabled when server.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -33,10 +33,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRole: enabled when global.tls.enabled=true and server.enabled=true" { +@test "tlsInit/Role: enabled when global.tls.enabled=true and server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=true' \ . | tee /dev/stderr | @@ -44,24 +44,24 @@ load _helpers [ "${actual}" = "true" ] } -@test "tlsInitCleanup/ClusterRole: enabled with global.tls.enabled" { +@test "tlsInit/Role: enabled with global.tls.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "tlsInitCleanup/ClusterRole: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { +@test "tlsInit/Role: adds pod security polices with global.tls.enabled and global.enablePodSecurityPolicies" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrole.yaml \ + -x templates/tls-init-role.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enablePodSecurityPolicies=true' \ . | tee /dev/stderr | yq -r '.rules[] | select(.resources==["podsecuritypolicies"]) | .resourceNames[0]' | tee /dev/stderr) - [ "${actual}" = "release-name-consul-tls-init-cleanup" ] + [ "${actual}" = "release-name-consul-tls-init" ] } diff --git a/test/unit/tls-init-cleanup-clusterrolebinding.bats b/test/unit/tls-init-rolebinding.bats similarity index 59% rename from test/unit/tls-init-cleanup-clusterrolebinding.bats rename to test/unit/tls-init-rolebinding.bats index d8d414e00c..c53a7a43a5 100644 --- a/test/unit/tls-init-cleanup-clusterrolebinding.bats +++ b/test/unit/tls-init-rolebinding.bats @@ -2,19 +2,19 @@ load _helpers -@test "tlsInitCleanup/ClusterRoleBinding: disabled by default" { +@test "tlsInit/RoleBinding: disabled by default" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + -x templates/tls-init-rolebinding.yaml \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRoleBinding: disabled with global.enabled=false" { +@test "tlsInit/RoleBinding: disabled with global.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + -x templates/tls-init-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'global.enabled=false' \ . | tee /dev/stderr | @@ -22,20 +22,20 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRoleBinding: enabled with global.tls.enabled" { +@test "tlsInit/RoleBinding: enabled with global.tls.enabled" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + -x templates/tls-init-rolebinding.yaml \ --set 'global.tls.enabled=true' \ . | tee /dev/stderr | yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "tlsInitCleanup/ClusterRoleBinding: disabled when server.enabled=false" { +@test "tlsInit/RoleBinding: disabled when server.enabled=false" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + -x templates/tls-init-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=false' \ . | tee /dev/stderr | @@ -43,10 +43,10 @@ load _helpers [ "${actual}" = "false" ] } -@test "tlsInitCleanup/ClusterRoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { +@test "tlsInit/RoleBinding: enabled when global.tls.enabled=true and server.enabled=true" { cd `chart_dir` local actual=$(helm template \ - -x templates/tls-init-cleanup-clusterrolebinding.yaml \ + -x templates/tls-init-rolebinding.yaml \ --set 'global.tls.enabled=true' \ --set 'server.enabled=true' \ . | tee /dev/stderr | From 6a3fbff48e3fbc3292a03dfabb886c049fcfbeb7 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 26 Jun 2020 09:13:40 -0700 Subject: [PATCH 386/739] Update CHANGELOG.md (#514) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f817409ff..95ab6970e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ FEATURES: BREAKING CHANGES: +* If upgrading to Consul 1.8.0 and using Consul Connect, you will need to upgrade consul-k8s to 0.16.0 (by setting `global.imageK8S: hashicorp/consul-k8s:0.16.0`) and re-roll your Connect pods so they get re-injected, before upgrading consul. This is required because we were previously setting a health check incorrectly that now fails on Consul 1.8.0. If you upgrade to 1.8.0 without upgrading to consul-k8s 0.16.0 and re-rolling your connect pods first, the connect pods will fail their health checks and no traffic will be routed to them. + * It is recommended to use the helm repository to install the helm chart instead of cloning this repo directly. Starting with this release the master branch may contain breaking changes. From bb4b92c9389c40a70618110ba0f1369773e9b860 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Mon, 29 Jun 2020 10:02:06 -0700 Subject: [PATCH 387/739] Helm 3 Tests (#463) * Test with Helm 2 and 3 --- .circleci/config.yml | 17 +- templates/client-config-configmap.yaml | 2 +- templates/client-daemonset.yaml | 2 +- templates/connect-inject-clusterrole.yaml | 2 +- templates/connect-inject-deployment.yaml | 2 +- templates/connect-inject-mutatingwebhook.yaml | 2 +- templates/connect-inject-service.yaml | 2 +- templates/dns-service.yaml | 2 +- templates/server-config-configmap.yaml | 2 +- templates/server-disruptionbudget.yaml | 2 +- templates/server-service.yaml | 2 +- templates/server-statefulset.yaml | 2 +- templates/sync-catalog-deployment.yaml | 2 +- templates/tls-init-cleanup-job.yaml | 2 +- templates/tls-init-job.yaml | 4 +- templates/ui-service.yaml | 2 +- test/unit/_helpers.bash | 38 ++++ test/unit/client-configmap.bats | 30 ++- test/unit/client-daemonset.bats | 190 ++++++++---------- test/unit/client-podsecuritypolicy.bats | 39 ++-- test/unit/client-role.bats | 30 ++- test/unit/client-rolebinding.bats | 22 +- test/unit/client-serviceaccount.bats | 24 +-- .../client-snapshot-agent-deployment.bats | 72 ++++--- ...ient-snapshot-agent-podsecuritypolicy.bats | 18 +- test/unit/client-snapshot-agent-role.bats | 26 +-- .../client-snapshot-agent-rolebinding.bats | 20 +- .../client-snapshot-agent-serviceaccount.bats | 20 +- ...connect-inject-authmethod-clusterrole.bats | 20 +- ...-inject-authmethod-clusterrolebinding.bats | 20 +- ...nect-inject-authmethod-serviceaccount.bats | 22 +- test/unit/connect-inject-clusterrole.bats | 38 ++-- .../connect-inject-clusterrolebinding.bats | 28 +-- test/unit/connect-inject-deployment.bats | 161 +++++++-------- test/unit/connect-inject-mutatingwebhook.bats | 28 +-- .../connect-inject-podsecuritypolicy.bats | 26 +-- test/unit/connect-inject-service.bats | 26 +-- test/unit/connect-inject-serviceaccount.bats | 30 ++- test/unit/create-federation-secret-job.bats | 44 ++-- ...e-federation-secret-podsecuritypolicy.bats | 18 +- test/unit/create-federation-secret-role.bats | 14 +- .../create-federation-secret-rolebinding.bats | 10 +- ...eate-federation-secret-serviceaccount.bats | 12 +- test/unit/dns-service.bats | 28 ++- test/unit/enterprise-license-job.bats | 55 +++-- .../enterprise-license-podsecuritypolicy.bats | 42 ++-- test/unit/enterprise-license-role.bats | 40 ++-- test/unit/enterprise-license-rolebinding.bats | 34 ++-- .../enterprise-license-serviceaccount.bats | 36 ++-- test/unit/helpers.bats | 32 +-- test/unit/ingress-gateways-deployment.bats | 143 +++++++------ .../ingress-gateways-podsecuritypolicy.bats | 12 +- test/unit/ingress-gateways-role.bats | 20 +- test/unit/ingress-gateways-rolebinding.bats | 12 +- test/unit/ingress-gateways-service.bats | 48 +++-- .../unit/ingress-gateways-serviceaccount.bats | 14 +- test/unit/mesh-gateway-clusterrole.bats | 20 +- .../unit/mesh-gateway-clusterrolebinding.bats | 13 +- test/unit/mesh-gateway-deployment.bats | 119 ++++++----- test/unit/mesh-gateway-podsecuritypolicy.bats | 10 +- test/unit/mesh-gateway-service.bats | 34 ++-- test/unit/mesh-gateway-serviceaccount.bats | 12 +- test/unit/server-acl-init-cleanup-job.bats | 32 ++- ...er-acl-init-cleanup-podsecuritypolicy.bats | 20 +- test/unit/server-acl-init-cleanup-role.bats | 24 +-- .../server-acl-init-cleanup-rolebinding.bats | 22 +- ...erver-acl-init-cleanup-serviceaccount.bats | 24 +-- test/unit/server-acl-init-job.bats | 140 ++++++------- .../server-acl-init-podsecuritypolicy.bats | 20 +- test/unit/server-acl-init-role.bats | 26 +-- test/unit/server-acl-init-rolebinding.bats | 22 +- test/unit/server-acl-init-serviceaccount.bats | 24 +-- test/unit/server-configmap.bats | 48 ++--- test/unit/server-disruptionbudget.bats | 42 ++-- test/unit/server-podsecuritypolicy.bats | 18 +- test/unit/server-role.bats | 26 +-- test/unit/server-rolebinding.bats | 22 +- test/unit/server-service.bats | 36 ++-- test/unit/server-serviceaccount.bats | 24 +-- test/unit/server-statefulset.bats | 136 ++++++------- test/unit/sync-catalog-clusterrole.bats | 36 ++-- .../unit/sync-catalog-clusterrolebinding.bats | 28 +-- test/unit/sync-catalog-deployment.bats | 119 ++++++----- test/unit/sync-catalog-podsecuritypolicy.bats | 26 +-- test/unit/sync-catalog-serviceaccount.bats | 30 ++- .../unit/terminating-gateways-deployment.bats | 114 ++++++----- ...erminating-gateways-podsecuritypolicy.bats | 12 +- test/unit/terminating-gateways-role.bats | 20 +- .../terminating-gateways-rolebinding.bats | 12 +- .../terminating-gateways-serviceaccount.bats | 14 +- test/unit/test-runner.bats | 10 +- test/unit/tls-init-cleanup-job.bats | 28 +-- .../tls-init-cleanup-podsecuritypolicy.bats | 26 +-- test/unit/tls-init-cleanup-role.bats | 30 ++- test/unit/tls-init-cleanup-rolebinding.bats | 28 +-- .../unit/tls-init-cleanup-serviceaccount.bats | 30 ++- test/unit/tls-init-job.bats | 34 ++-- test/unit/tls-init-podsecuritypolicy.bats | 26 +-- test/unit/tls-init-role.bats | 30 ++- test/unit/tls-init-rolebinding.bats | 28 +-- test/unit/tls-init-serviceaccount.bats | 30 ++- test/unit/ui-service.bats | 64 +++--- 102 files changed, 1472 insertions(+), 1808 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index efb3e4c025..c780ba09d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,11 +3,20 @@ orbs: slack: circleci/slack@3.4.2 jobs: - unit: + unit-helm2: docker: # This image is built from test/docker/Test.dockerfile - image: hashicorpdev/consul-helm-test:0.3.0 + steps: + - checkout + - run: + name: Run Unit Tests + command: bats ./test/unit + unit-helm3: + docker: + - image: hashicorpdev/consul-helm-test:0.4.0 + steps: - checkout @@ -74,10 +83,12 @@ workflows: version: 2 test: jobs: - - unit + - unit-helm2 + - unit-helm3 - acceptance: requires: - - unit + - unit-helm2 + - unit-helm3 filters: branches: only: master diff --git a/templates/client-config-configmap.yaml b/templates/client-config-configmap.yaml index e96f50ff30..c9736ff650 100644 --- a/templates/client-config-configmap.yaml +++ b/templates/client-config-configmap.yaml @@ -1,6 +1,6 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} # ConfigMap with extra configuration specified directly to the chart # for client agents only. -{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: v1 kind: ConfigMap metadata: diff --git a/templates/client-daemonset.yaml b/templates/client-daemonset.yaml index a48934c239..35dd04b78b 100644 --- a/templates/client-daemonset.yaml +++ b/templates/client-daemonset.yaml @@ -1,5 +1,5 @@ -# DaemonSet to run the Consul clients on every node. {{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +# DaemonSet to run the Consul clients on every node. apiVersion: apps/v1 kind: DaemonSet metadata: diff --git a/templates/connect-inject-clusterrole.yaml b/templates/connect-inject-clusterrole.yaml index 58783c0833..b2f890098f 100644 --- a/templates/connect-inject-clusterrole.yaml +++ b/templates/connect-inject-clusterrole.yaml @@ -1,5 +1,5 @@ -# The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration. {{- if and (not .Values.connectInject.certs.secretName) (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration. apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/templates/connect-inject-deployment.yaml b/templates/connect-inject-deployment.yaml index ab66cbfb10..893e825bac 100644 --- a/templates/connect-inject-deployment.yaml +++ b/templates/connect-inject-deployment.yaml @@ -1,7 +1,7 @@ -# The deployment for running the Connect sidecar injector {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}{{ fail "clients must be enabled for connect injection" }}{{ end }} {{- if not .Values.client.grpc }}{{ fail "client.grpc must be true for connect injection" }}{{ end }} +# The deployment for running the Connect sidecar injector apiVersion: apps/v1 kind: Deployment metadata: diff --git a/templates/connect-inject-mutatingwebhook.yaml b/templates/connect-inject-mutatingwebhook.yaml index 2ca5762456..00c011c039 100644 --- a/templates/connect-inject-mutatingwebhook.yaml +++ b/templates/connect-inject-mutatingwebhook.yaml @@ -1,5 +1,5 @@ -# The MutatingWebhookConfiguration to enable the Connect injector. {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The MutatingWebhookConfiguration to enable the Connect injector. apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: diff --git a/templates/connect-inject-service.yaml b/templates/connect-inject-service.yaml index 45dc2b32db..8004d8277d 100644 --- a/templates/connect-inject-service.yaml +++ b/templates/connect-inject-service.yaml @@ -1,5 +1,5 @@ -# The service for the Connect sidecar injector {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The service for the Connect sidecar injector apiVersion: v1 kind: Service metadata: diff --git a/templates/dns-service.yaml b/templates/dns-service.yaml index 1d37abc8ac..30b41e1787 100644 --- a/templates/dns-service.yaml +++ b/templates/dns-service.yaml @@ -1,5 +1,5 @@ -# Service for Consul DNS. {{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.global.enabled)) }} +# Service for Consul DNS. apiVersion: v1 kind: Service metadata: diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 7b64e45c2c..59ad7e033d 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -1,5 +1,5 @@ -# StatefulSet to run the actual Consul server cluster. {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +# StatefulSet to run the actual Consul server cluster. apiVersion: v1 kind: ConfigMap metadata: diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index 01bef39964..fe372bf17b 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -1,6 +1,6 @@ +{{- if (and .Values.server.disruptionBudget.enabled (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} # PodDisruptionBudget to prevent degrading the server cluster through # voluntary cluster changes. -{{- if (and .Values.server.disruptionBudget.enabled (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: diff --git a/templates/server-service.yaml b/templates/server-service.yaml index b32e084e95..a6003f9ec3 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -1,9 +1,9 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} # Headless service for Consul server DNS entries. This service should only # point to Consul servers. For access to an agent, one should assume that # the agent is installed locally on the node and the NODE_IP should be used. # If the node can't run a Consul agent, then this service can be used to # communicate directly to a server agent. -{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} apiVersion: v1 kind: Service metadata: diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 55d9586e13..95ed0bd70f 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -1,7 +1,7 @@ -# StatefulSet to run the actual Consul server cluster. {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if and .Values.global.federation.enabled (not .Values.global.tls.enabled) }}{{ fail "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" }}{{ end }} {{- if and .Values.global.federation.enabled (not .Values.meshGateway.enabled) }}{{ fail "If global.federation.enabled is true, meshGateway.enabled must be true because mesh gateways are required for federation" }}{{ end }} +# StatefulSet to run the actual Consul server cluster. apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/templates/sync-catalog-deployment.yaml b/templates/sync-catalog-deployment.yaml index 0879962826..4c5d99f41b 100644 --- a/templates/sync-catalog-deployment.yaml +++ b/templates/sync-catalog-deployment.yaml @@ -1,5 +1,5 @@ -# The deployment for running the sync-catalog pod {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +# The deployment for running the sync-catalog pod apiVersion: apps/v1 kind: Deployment metadata: diff --git a/templates/tls-init-cleanup-job.yaml b/templates/tls-init-cleanup-job.yaml index 5e50f50870..396df02633 100644 --- a/templates/tls-init-cleanup-job.yaml +++ b/templates/tls-init-cleanup-job.yaml @@ -1,6 +1,6 @@ -# tls-init-cleanup job deletes Kubernetes secrets created by tls-init {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} +# tls-init-cleanup job deletes Kubernetes secrets created by tls-init apiVersion: batch/v1 kind: Job metadata: diff --git a/templates/tls-init-job.yaml b/templates/tls-init-job.yaml index bc00f584cb..dc2934b199 100644 --- a/templates/tls-init-job.yaml +++ b/templates/tls-init-job.yaml @@ -1,7 +1,7 @@ -# tls-init job generate Consul cluster CA and certificates for the Consul servers -# and creates Kubernetes secrets for them. {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if .Values.global.tls.enabled }} +# tls-init job generate Consul cluster CA and certificates for the Consul servers +# and creates Kubernetes secrets for them. apiVersion: batch/v1 kind: Job metadata: diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index 0df5776b45..5da93089ba 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -1,5 +1,5 @@ -# UI Service for Consul Server {{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }} +# UI Service for Consul Server apiVersion: v1 kind: Service metadata: diff --git a/test/unit/_helpers.bash b/test/unit/_helpers.bash index 530b66e8c3..8902881bf3 100644 --- a/test/unit/_helpers.bash +++ b/test/unit/_helpers.bash @@ -2,3 +2,41 @@ chart_dir() { echo ${BATS_TEST_DIRNAME}/../.. } + +# helm is used to intercept the `helm` command in tests and change flags depending +# on which version is being run. +# Helm 2 uses the -x flag instead of -s. +# NOTE: command is used so that this function isn't called recursively. +helm() { + if [[ $(v2) ]]; then + command helm template -x "${@:3}" + else + # The release name in Helm 3 defaults to RELEASE-NAME whereas it's lowercaes + # in Helm 3 so we need to set it explictly. + command helm template release-name -s "${@:3}" + fi +} + +# Usage: assert_empty helm template -s