Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support of consul namespaces to health checks #376

Merged
merged 15 commits into from
Nov 5, 2020
12 changes: 12 additions & 0 deletions connect-inject/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ const (

// injected is used as the annotation value for annotationInjected
injected = "injected"

// annotationConsulNamespace is the Consul namespace the service is registered into.
annotationConsulNamespace = "consul.hashicorp.com/consul-namespace"
)

var (
Expand Down Expand Up @@ -360,6 +363,15 @@ func (h *Handler) Mutate(req *v1beta1.AdmissionRequest) *v1beta1.AdmissionRespon
labelInject: injected,
})...)

// Consul-ENT only: Add the Consul destination namespace as an annotation to the pod.
if h.EnableNamespaces {
patches = append(patches, updateAnnotation(
pod.Annotations,
map[string]string{
annotationConsulNamespace: h.consulNamespace(req.Namespace),
})...)
}

// Generate the patch
var patch []byte
if len(patches) > 0 {
Expand Down
87 changes: 87 additions & 0 deletions connect-inject/handler_ent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package connectinject

import (
"encoding/json"
"testing"
"time"

Expand All @@ -11,6 +12,7 @@ import (
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/go-hclog"
"github.com/mattbaird/jsonpatch"
"github.com/stretchr/testify/require"
"k8s.io/api/admission/v1beta1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -508,3 +510,88 @@ func TestHandler_MutateWithNamespaces_ACLs(t *testing.T) {
})
}
}

// Test that the annotation for the Consul namespace is added.
func TestHandler_MutateWithNamespaces_Annotation(t *testing.T) {
t.Parallel()
sourceKubeNS := "kube-ns"

cases := map[string]struct {
ConsulDestinationNamespace string
Mirroring bool
MirroringPrefix string
ExpNamespaceAnnotation string
}{
"dest: default": {
ConsulDestinationNamespace: "default",
ExpNamespaceAnnotation: "default",
},
"dest: foo": {
ConsulDestinationNamespace: "foo",
ExpNamespaceAnnotation: "foo",
},
"mirroring": {
Mirroring: true,
ExpNamespaceAnnotation: sourceKubeNS,
},
"mirroring with prefix": {
Mirroring: true,
MirroringPrefix: "prefix-",
ExpNamespaceAnnotation: "prefix-" + sourceKubeNS,
},
}

for name, c := range cases {
t.Run(name, func(t *testing.T) {
require := require.New(t)

// Set up consul server
a, err := testutil.NewTestServerConfigT(t, nil)
require.NoError(err)
defer a.Stop()

// Set up consul client
client, err := api.NewClient(&api.Config{
Address: a.HTTPAddr,
})
require.NoError(err)

handler := Handler{
Log: hclog.Default().Named("handler"),
AllowK8sNamespacesSet: mapset.NewSet("*"),
DenyK8sNamespacesSet: mapset.NewSet(),
EnableNamespaces: true,
ConsulDestinationNamespace: c.ConsulDestinationNamespace,
EnableK8SNSMirroring: c.Mirroring,
K8SNSMirroringPrefix: c.MirroringPrefix,
ConsulClient: client,
}

resp := handler.Mutate(&v1beta1.AdmissionRequest{
Object: encodeRaw(t, &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "web",
},
},
},
}),
Namespace: sourceKubeNS,
})
require.Equal(resp.Allowed, true)

// Check that the annotation was added as a patch.
var consulNamespaceAnnotationValue string
var patches []jsonpatch.JsonPatchOperation
require.NoError(json.Unmarshal(resp.Patch, &patches))
for _, patch := range patches {
if patch.Path == "/metadata/annotations/"+escapeJSONPointer(annotationConsulNamespace) {
consulNamespaceAnnotationValue = patch.Value.(string)
}
}
require.NotEmpty(consulNamespaceAnnotationValue, "no namespace annotation set")
require.Equal(c.ExpNamespaceAnnotation, consulNamespaceAnnotationValue)
})
}
}
1 change: 1 addition & 0 deletions connect-inject/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ func TestHandlerHandle(t *testing.T) {
},
},
},

{
"pod with existing label",
Handler{
Expand Down
3 changes: 3 additions & 0 deletions connect-inject/health_check_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ func (h *HealthCheckResource) getConsulClient(pod *corev1.Pod) (*api.Client, err
newAddr := fmt.Sprintf("%s://%s:%s", h.ConsulUrl.Scheme, pod.Status.HostIP, h.ConsulUrl.Port())
localConfig := api.DefaultConfig()
localConfig.Address = newAddr
if pod.Annotations[annotationConsulNamespace] != "" {
localConfig.Namespace = pod.Annotations[annotationConsulNamespace]
}
localClient, err := api.NewClient(localConfig)
if err != nil {
h.Log.Error("unable to get Consul API Client", "addr", newAddr, "err", err)
Expand Down
Loading