Skip to content
This repository was archived by the owner on Aug 25, 2021. It is now read-only.

Add ingress option #774

Merged
merged 6 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
IMPROVEMENTS:
* Use `consul-k8s` subcommand to perform `tls-init` job. This allows for server certificates to get rotated on subsequent runs.
Consul servers have to be restarted in order for them to update their server certificates [[GH-749](https://github.com/hashicorp/consul-helm/pull/721)]
* Add support for Ingress resource for Consul UI [[GH-774](https://github.com/hashicorp/consul-helm/pull/774)]

## 0.28.0 (Dec 21, 2020)

Expand Down
1 change: 1 addition & 0 deletions hack/helm-reference-gen/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
Expand Down
46 changes: 46 additions & 0 deletions templates/ui-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{{- 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))) }}
{{- if (and (ne (.Values.ui.ingress.enabled | toString) "-") .Values.ui.ingress.enabled) }}
{{- $serviceName := printf "%s-%s" (include "consul.fullname" .) "ui" -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
name: {{ template "consul.fullname" . }}-ingress
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: ui
{{- if .Values.ui.ingress.annotations }}
annotations:
{{ tpl .Values.ui.ingress.annotations . | nindent 4 | trim }}
{{- end}}
spec:
rules:
{{ $global := .Values.global }}
{{- range .Values.ui.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range (.paths | default (list "/")) }}
{{- if (or (not $global.tls.enabled) (not $global.tls.httpsOnly)) }}
- backend:
serviceName: {{ $serviceName }}
servicePort: 80
path: {{ . }}
{{- end }}
{{- if $global.tls.enabled }}
- backend:
serviceName: {{ $serviceName }}
servicePort: 443
path: {{ . }}
{{- end }}
{{- end }}
{{- end -}}
{{- if .Values.ui.ingress.tls }}
tls:
{{- toYaml .Values.ui.ingress.tls | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
166 changes: 166 additions & 0 deletions test/unit/ui-ingress.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env bats

load _helpers

@test "ui/Ingress: disabled by default" {
cd `chart_dir`
assert_empty helm template \
-s templates/ui-ingress.yaml \
.
}

@test "ui/Ingress: enable with ui.ingress.enabled" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
. | tee /dev/stderr |
yq 'length > 0' | tee /dev/stderr)
[ "${actual}" = "true" ]
}

@test "ui/Ingress: disable with ui.ingress.enabled" {
cd `chart_dir`
assert_empty helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=false' \
.
}

@test "ui/Ingress: disable with ui.ingress.enabled dash string" {
cd `chart_dir`
assert_empty helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=-' \
.
}

#--------------------------------------------------------------------
# hosts

@test "ui/Ingress: no hosts by default" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
. | tee /dev/stderr |
yq -r '.spec.rules' | tee /dev/stderr)
[ "${actual}" = "null" ]
}

@test "ui/Ingress: hosts can be set" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'ui.ingress.hosts[0].host=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.rules[0].host' | tee /dev/stderr)
[ "${actual}" = "foo.com" ]
}

@test "ui/Ingress: exposes single port 80 when global.tls.enabled=false" {
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'global.tls.enabled=false' \
--set 'ui.ingress.hosts[0].host=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr)
[ "${actual}" = "80" ]
}

@test "ui/Ingress: exposes single port 443 when global.tls.enabled=true and global.tls.httpsOnly=true" {
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'global.tls.enabled=true' \
--set 'ui.ingress.hosts[0].host=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr)
[ "${actual}" = "443" ]
}

@test "ui/Ingress: exposes the port 80 when global.tls.enabled=true and global.tls.httpsOnly=false" {
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'global.tls.enabled=true' \
--set 'global.tls.httpsOnly=false' \
--set 'ui.ingress.hosts[0].host=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.rules[0].http.paths[0].backend.servicePort' | tee /dev/stderr)
[ "${actual}" = "80" ]
}

@test "ui/Ingress: exposes the port 443 when global.tls.enabled=true and global.tls.httpsOnly=false" {
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'global.tls.enabled=true' \
--set 'global.tls.httpsOnly=false' \
--set 'ui.ingress.hosts[0].host=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.rules[0].http.paths[1].backend.servicePort' | tee /dev/stderr)
[ "${actual}" = "443" ]
}

#--------------------------------------------------------------------
# tls

@test "ui/Ingress: no tls by default" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
. | tee /dev/stderr |
yq -r '.spec.tls' | tee /dev/stderr)
[ "${actual}" = "null" ]
}

@test "ui/Ingress: tls can be set" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'ui.ingress.tls[0].hosts[0]=foo.com' \
. | tee /dev/stderr |
yq -r '.spec.tls[0].hosts[0]' | tee /dev/stderr)
[ "${actual}" = "foo.com" ]
}

@test "ui/Ingress: tls with secret name can be set" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'ui.ingress.tls[0].hosts[0]=sslexample.foo.com' \
--set 'ui.ingress.tls[0].secretName=testsecret-tls' \
. | tee /dev/stderr |
yq -r '.spec.tls[0].secretName' | tee /dev/stderr)
[ "${actual}" = "testsecret-tls" ]
}

#--------------------------------------------------------------------
# annotations

@test "ui/Ingress: no annotations by default" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
. | tee /dev/stderr |
yq -r '.metadata.annotations' | tee /dev/stderr)
[ "${actual}" = "null" ]
}

@test "ui/Ingress: annotations can be set" {
cd `chart_dir`
local actual=$(helm template \
-s templates/ui-ingress.yaml \
--set 'ui.ingress.enabled=true' \
--set 'ui.ingress.annotations=foo: bar' \
. | tee /dev/stderr |
yq -r '.metadata.annotations.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}
46 changes: 46 additions & 0 deletions values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,52 @@ ui:
# @type: string
additionalSpec: null

# Configure Ingress for the Consul UI.
# If `global.tls.enabled` is set to `true`, the Ingress will expose
# the port 443 on the UI service. Please ensure the Ingress Controller
# supports SSL pass-through and it is enabled to ensure traffic forwarded
# to port 443 has not been TLS terminated.
ingress:
# This will create an Ingress resource for the Consul UI.
# @type: boolean
enabled: false

# hosts is a list of host name to create Ingress rules.
#
# ```yaml
# hosts:
# - host: foo.bar
# paths:
# - /example
# - /test
# ```
#
# @type: array<map>
hosts: []

# tls is a list of hosts and secret name in an Ingress
# which tells the Ingress controller to secure the channel.
Comment on lines +967 to +968
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we tell them what secret to use? Do they need to use passthrough TLS if consul tls is enabled?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i realized in my tinkering that i hadn't tested the only TLS (https only enabled) options. ie, the 80 port was always open on the service. the ingress resource always performs TLS termination so we cant point traffic to 443 as the request that reached the service will always be HTTP. I guess it doesnt make sense for this PR to support port 443 in that case, and ill make the requisite changes.

#
# ```yaml
# tls:
# - hosts:
# - chart-example.local
# secretName: testsecret-tls
# ```
# @type: array<map>
tls: []

# Annotations to apply to the UI ingress.
#
# Example:
#
# ```yaml
# annotations: |
# 'annotation-key': annotation-value
# ```
# @type: string
annotations: null

# Configure 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).
Expand Down