Skip to content

Commit

Permalink
Prevent extra-config from being loaded twice (and erroring for segmen…
Browse files Browse the repository at this point in the history
…t config) on clients and servers (#3337)

* wip:  testing with server works when you add segments as extraValues.
Todos:
* make similar changes to clients
* potentially upgrade test?
* consider locality having its own volume, rather than 2 volumes with extra in them

* move extra-config out of /consul/config so it does not get applied twice

* add comments about use of additional config maps

* remove temporary inclusion of values.yaml in root that was used for hand off

* get rid of temporary config.file

* add segments test

* test using 3 servers in a single cluster

* add changelog

* fix linting issues.

* add comment to test. remove extra lines from config map.

* fix bats tests

---------

Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
  • Loading branch information
jmurret and ndhanushkodi committed Dec 14, 2023
1 parent e2dc674 commit b81182f
Show file tree
Hide file tree
Showing 16 changed files with 363 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .changelog/3337.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug-fix
mesh: prevent extra-config from being loaded twice (and erroring for segment config) on clients and servers.
```
18 changes: 18 additions & 0 deletions acceptance/tests/segments/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package segments

import (
"os"
"testing"

testsuite "github.com/hashicorp/consul-k8s/acceptance/framework/suite"
)

var suite testsuite.Suite

func TestMain(m *testing.M) {
suite = testsuite.NewSuite(m)
os.Exit(suite.Run())
}
187 changes: 187 additions & 0 deletions acceptance/tests/segments/segments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package segments

import (
"context"
"testing"

"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/hashicorp/consul-k8s/acceptance/framework/connhelper"
"github.com/hashicorp/consul-k8s/acceptance/framework/consul"
"github.com/hashicorp/consul-k8s/acceptance/framework/helpers"
"github.com/hashicorp/consul-k8s/acceptance/framework/k8s"
"github.com/hashicorp/consul-k8s/acceptance/framework/logger"
)

// TestSegments_MeshWithAgentfulClients is a simple test that verifies that
// the Consul service mesh can be configured to use segments with:
// - one cluster with an alpha segment configured on the servers.
// - clients enabled and joining the alpha segment.
// - static client can communicate with static server.
func TestSegments_MeshWithAgentfulClients(t *testing.T) {
cases := map[string]struct {
secure bool
}{
"not-secure": {secure: false},
"secure": {secure: true},
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
cfg := suite.Config()
if !cfg.EnableEnterprise {
t.Skipf("skipping this test because -enable-enterprise is not set")
}
ctx := suite.Environment().DefaultContext(t)

releaseName := helpers.RandomName()

helmValues := map[string]string{
"connectInject.enabled": "true",

"server.replicas": "3",
"server.extraConfig": `"{\"segments\": [{\"name\":\"alpha1\"\,\"bind\":\"0.0.0.0\"\,\"port\":8303}]}"`,

"client.enabled": "true",
// need to configure clients to connect to port 8303 that the alpha segment was configured on rather than
// the standard serf LAN port.
"client.join[0]": "${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[1]": "${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[2]": "${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.extraConfig": `"{\"segment\": \"alpha1\"}"`,
}

connHelper := connhelper.ConnectHelper{
ClusterKind: consul.Helm,
Secure: c.secure,
ReleaseName: releaseName,
Ctx: ctx,
UseAppNamespace: cfg.EnableRestrictedPSAEnforcement,
Cfg: cfg,
HelmValues: helmValues,
}

connHelper.Setup(t)

connHelper.Install(t)
connHelper.DeployClientAndServer(t)
if c.secure {
connHelper.TestConnectionFailureWithoutIntention(t, connhelper.ConnHelperOpts{})
connHelper.CreateIntention(t, connhelper.IntentionOpts{})
}

connHelper.TestConnectionSuccess(t, connhelper.ConnHelperOpts{})
connHelper.TestConnectionFailureWhenUnhealthy(t)
})
}
}

// TestSegments_MeshWithAgentfulClientsMultiCluster is a simple test that verifies that
// the Consul service mesh can be configured to use segments with:
// - one cluster with an alpha segment configured on the servers.
// - clients enabled on another cluster and joining the alpha segment.
// - static client can communicate with static server.
func TestSegments_MeshWithAgentfulClientsMultiCluster(t *testing.T) {
cases := map[string]struct {
secure bool
}{
"not-secure": {secure: false},
"secure": {secure: true},
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
cfg := suite.Config()
if !cfg.EnableEnterprise {
t.Skipf("skipping this test because -enable-enterprise is not set")
}
releaseName := helpers.RandomName()

// deploy server cluster
serverClusterContext := suite.Environment().DefaultContext(t)
serverClusterHelmValues := map[string]string{
"connectInject.enabled": "true",

"server.replicas": "3",
"server.extraConfig": `"{\"segments\": [{\"name\":\"alpha1\"\,\"bind\":\"0.0.0.0\"\,\"port\":8303}]}"`,

"client.enabled": "true",
"client.join[0]": "${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[1]": "${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[2]": "${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.extraConfig": `"{\"segment\": \"alpha1\"}"`,
}

serverConnHelper := connhelper.ConnectHelper{
ClusterKind: consul.Helm,
Secure: c.secure,
ReleaseName: releaseName,
Ctx: serverClusterContext,
UseAppNamespace: cfg.EnableRestrictedPSAEnforcement,
Cfg: cfg,
HelmValues: serverClusterHelmValues,
}

serverConnHelper.Setup(t)
serverConnHelper.Install(t)
serverConnHelper.DeployServer(t)

// deploy client cluster
clientClusterContext := suite.Environment().Context(t, 1)
clientClusterHelmValues := map[string]string{
"connectInject.enabled": "true",

"server.enabled": "false",

"client.enabled": "true",
"client.join[0]": "${CONSUL_FULLNAME}-server-0.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[1]": "${CONSUL_FULLNAME}-server-1.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.join[2]": "${CONSUL_FULLNAME}-server-2.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:8303",
"client.extraConfig": `"{\"segment\": \"alpha1\"}"`,
}

clientClusterConnHelper := connhelper.ConnectHelper{
ClusterKind: consul.Helm,
Secure: c.secure,
ReleaseName: releaseName,
Ctx: clientClusterContext,
UseAppNamespace: cfg.EnableRestrictedPSAEnforcement,
Cfg: cfg,
HelmValues: clientClusterHelmValues,
}

clientClusterConnHelper.Setup(t)
clientClusterConnHelper.Install(t)
logger.Log(t, "creating static-client deployments in client cluster")
opts := clientClusterConnHelper.KubectlOptsForApp(t)

if cfg.EnableTransparentProxy {
k8s.DeployKustomize(t, opts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy")
} else {
k8s.DeployKustomize(t, opts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject")
}

// Check that the static-client has been injected and now have 2 containers in client cluster.
for _, labelSelector := range []string{"app=static-client"} {
podList, err := clientClusterContext.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), metav1.ListOptions{
LabelSelector: labelSelector,
})
require.NoError(t, err)
require.Len(t, podList.Items, 1)
require.Len(t, podList.Items[0].Spec.Containers, 2)
}

//if c.secure {
// connHelper.TestConnectionFailureWithoutIntention(t, connhelper.ConnHelperOpts{})
// connHelper.CreateIntention(t, connhelper.IntentionOpts{})
//}
//
//connHelper.TestConnectionSuccess(t, connhelper.ConnHelperOpts{})
//connHelper.TestConnectionFailureWhenUnhealthy(t)
})
}
}
2 changes: 1 addition & 1 deletion charts/consul/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ substitution for HOST_IP/POD_IP/HOSTNAME. Useful for dogstats telemetry. The out
is passed to consul as a -config-file param on command line.
*/}}
{{- define "consul.extraconfig" -}}
cp /consul/config/extra-from-values.json /consul/extra-config/extra-from-values.json
cp /consul/tmp/extra-config/extra-from-values.json /consul/extra-config/extra-from-values.json
[ -n "${HOST_IP}" ] && sed -Ei "s|HOST_IP|${HOST_IP?}|g" /consul/extra-config/extra-from-values.json
[ -n "${POD_IP}" ] && sed -Ei "s|POD_IP|${POD_IP?}|g" /consul/extra-config/extra-from-values.json
[ -n "${HOSTNAME}" ] && sed -Ei "s|HOSTNAME|${HOSTNAME?}|g" /consul/extra-config/extra-from-values.json
Expand Down
3 changes: 0 additions & 3 deletions charts/consul/templates/client-config-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ data:
"log_level": "{{ .Values.client.logLevel | upper }}"
{{- end }}
}
extra-from-values.json: |-
{{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }}
central-config.json: |-
{
"enable_central_service_config": true
}
{{- if .Values.connectInject.enabled }}
{{/* We set check_update_interval to 0s so that check output is immediately viewable
in the UI. */}}
Expand Down
9 changes: 7 additions & 2 deletions charts/consul/templates/client-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ spec:
{{- end }}
{{- end }}
"consul.hashicorp.com/connect-inject": "false"
"consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/client-config-configmap.yaml") . | sha256sum }}
"consul.hashicorp.com/config-checksum": {{ print (include (print $.Template.BasePath "/client-config-configmap.yaml") .) (include (print $.Template.BasePath "/client-tmp-extra-config-configmap.yaml") .) | sha256sum }}
{{- if .Values.client.annotations }}
{{- tpl .Values.client.annotations . | nindent 8 }}
{{- end }}
Expand Down Expand Up @@ -141,6 +141,9 @@ spec:
- name: consul-data
emptyDir:
medium: "Memory"
- name: tmp-extra-config
configMap:
name: {{ template "consul.fullname" . }}-client-tmp-extra-config
{{- if .Values.global.tls.enabled }}
{{- if not .Values.global.secretsBackend.vault.enabled }}
- name: consul-ca-cert
Expand Down Expand Up @@ -389,7 +392,7 @@ spec:
{{- range $value := .Values.global.recursors }}
-recursor={{ quote $value }} \
{{- end }}
-config-file=/consul/extra-config/extra-from-values.json \
-config-dir=/consul/extra-config \
-domain={{ .Values.global.domain }}
volumeMounts:
- name: data
Expand All @@ -398,6 +401,8 @@ spec:
mountPath: /consul/config
- name: extra-config
mountPath: /consul/extra-config
- name: tmp-extra-config
mountPath: /consul/tmp/extra-config
- mountPath: /consul/login
name: consul-data
readOnly: true
Expand Down
21 changes: 21 additions & 0 deletions charts/consul/templates/client-tmp-extra-config-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }}
# ConfigMap that is used as a temporary landing spot so that the container command
# in the client-daemonset where it needs to be transformed. ConfigMaps create
# read only volumes so it needs to be copied and transformed to the extra-config
# emptyDir volume where all final extra cofngi lives for use in consul. (locality-init
# also writes to extra-config volume.)
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "consul.fullname" . }}-client-tmp-extra-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: client
data:
extra-from-values.json: |-
{{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }}
{{- end }}
2 changes: 0 additions & 2 deletions charts/consul/templates/server-config-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ data:
{{- end }}
{{- end }}
{{- end }}
extra-from-values.json: |-
{{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }}
{{- if .Values.global.acls.manageSystemACLs }}
acl-config.json: |-
{
Expand Down
10 changes: 7 additions & 3 deletions charts/consul/templates/server-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ spec:
{{- end }}
{{- end }}
"consul.hashicorp.com/connect-inject": "false"
"consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/server-config-configmap.yaml") . | sha256sum }}
"consul.hashicorp.com/config-checksum": {{ print (include (print $.Template.BasePath "/server-config-configmap.yaml") .) (include (print $.Template.BasePath "/server-tmp-extra-config-configmap.yaml") .) | sha256sum }}
{{- if .Values.server.annotations }}
{{- tpl .Values.server.annotations . | nindent 8 }}
{{- end }}
Expand Down Expand Up @@ -158,6 +158,9 @@ spec:
name: {{ template "consul.fullname" . }}-server-config
- name: extra-config
emptyDir: {}
- name: tmp-extra-config
configMap:
name: {{ template "consul.fullname" . }}-server-tmp-extra-config
{{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }}
- name: consul-ca-cert
secret:
Expand Down Expand Up @@ -421,8 +424,7 @@ spec:
-config-dir=/consul/userconfig/{{ .name }} \
{{- end }}
{{- end }}
-config-file=/consul/extra-config/extra-from-values.json \
-config-file=/consul/extra-config/locality.json
-config-dir=/consul/extra-config \
{{- if and .Values.global.cloud.enabled .Values.global.cloud.resourceId.secretName }}
-hcl="cloud { resource_id = \"${HCP_RESOURCE_ID}\" }"
{{- end }}
Expand All @@ -433,6 +435,8 @@ spec:
mountPath: /consul/config
- name: extra-config
mountPath: /consul/extra-config
- name: tmp-extra-config
mountPath: /consul/tmp/extra-config
{{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }}
- name: consul-ca-cert
mountPath: /consul/tls/ca/
Expand Down
21 changes: 21 additions & 0 deletions charts/consul/templates/server-tmp-extra-config-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
# ConfigMap that is used as a temporary landing spot so that the container command
# in the server-stateful set where it needs to be transformed. ConfigMaps create
# read only volumes so it needs to be copied and transformed to the extra-config
# emptyDir volume where all final extra cofngi lives for use in consul. (locality-init
# also writes to extra-config volume.)
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "consul.fullname" . }}-server-tmp-extra-config
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "consul.name" . }}
chart: {{ template "consul.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: server
data:
extra-from-values.json: |-
{{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }}
{{- end }}
11 changes: 0 additions & 11 deletions charts/consul/test/unit/client-config-configmap.bats
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@ load _helpers
.
}

@test "client/ConfigMap: extraConfig is set" {
cd `chart_dir`
local actual=$(helm template \
-s templates/client-config-configmap.yaml \
--set 'client.enabled=true' \
--set 'client.extraConfig="{\"hello\": \"world\"}"' \
. | tee /dev/stderr |
yq '.data["extra-from-values.json"] | match("world") | length > 1' | tee /dev/stderr)
[ "${actual}" = "true" ]
}

#--------------------------------------------------------------------
# connectInject.centralConfig [DEPRECATED]

Expand Down
Loading

0 comments on commit b81182f

Please sign in to comment.