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

adding sidecarEnvJson annotation #726

Merged
merged 4 commits into from
Sep 11, 2023
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
8 changes: 8 additions & 0 deletions pkg/inject/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ const (
//
AppMeshEnvAnnotation = "appmesh.k8s.aws/sidecarEnv"

// AppMeshEnvJsonAnnotation which is similar AppMeshEnvAnnotation, but it is used to specify the list Jsons of environment variables that need to be programmed on Envoy sidecars
// Here's how a sample annotations will be like
//
// e.g. appmesh.k8s.aws/sidecarEnvJson: '[{"DD_ENV":"prod","TEST_ENV":"env_val"}]'
// e.g. appmesh.k8s.aws/sidecarEnvJson: '[{"DD_ENV":"prod"}]'
//
AppMeshEnvJsonAnnotation = "appmesh.k8s.aws/sidecarEnvJson"

// === begin xray daemon annotations ===

// AppMeshXrayAgentConfigAnnotation specifies the mount path for the Xray daemon's configuration file.
Expand Down
32 changes: 32 additions & 0 deletions pkg/inject/envoy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package inject

import (
"fmt"
"k8s.io/apimachinery/pkg/util/json"
"strconv"
"strings"

Expand Down Expand Up @@ -92,6 +93,15 @@ func (m *envoyMutator) mutate(pod *corev1.Pod) error {
return err
}

customEnvJson, err := m.getCustomEnvJson(pod)
if err != nil {
return err
}
if customEnvJson != nil {
for k, v := range customEnvJson {
customEnv[k] = v
}
}
container, err := buildEnvoySidecar(variables, customEnv)
if err != nil {
return err
Expand Down Expand Up @@ -249,6 +259,28 @@ func (m *envoyMutator) getCustomEnv(pod *corev1.Pod) (map[string]string, error)
return customEnv, nil
}

func (m *envoyMutator) getCustomEnvJson(pod *corev1.Pod) (map[string]string, error) {
var temp []map[string]interface{}
customEnvJson := make(map[string]string)
if v, ok := pod.ObjectMeta.Annotations[AppMeshEnvJsonAnnotation]; ok {
err := json.Unmarshal([]byte(v), &temp)
for _, item := range temp {
for key, value := range item {
if strValue, isString := value.(string); isString {
customEnvJson[key] = strValue
} else {
return nil, errors.Errorf("nested json isn't supported with this annotation %s, expected format: %s", AppMeshEnvJsonAnnotation, `[{"DD_ENV":"prod","TEST_ENV":"env_val"}]`)
}
}
}
if err != nil {
err = errors.Errorf("malformed annotation %s, expected format: %s", AppMeshEnvJsonAnnotation, `[{"DD_ENV":"prod","TEST_ENV":"env_val"}]`)
return nil, err
}
}
return customEnvJson, nil
}

func (m *envoyMutator) mutateVolumeMounts(pod *corev1.Pod, envoyContainer *corev1.Container, volumeMounts map[string]string) {
for volumeName, mountPath := range volumeMounts {
volumeMount := corev1.VolumeMount{
Expand Down
93 changes: 93 additions & 0 deletions pkg/inject/envoy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3510,6 +3510,99 @@ func Test_envoyMutator_getCustomEnv(t *testing.T) {
})
}
}
func Test_envoyMutator_getCustomEnvJson(t *testing.T) {
type args struct {
pod *corev1.Pod
}
tests := []struct {
name string
args args
want map[string]string
wantErr error
}{
{
name: "pods with valid appmesh.k8s.aws/sidecarEnvJson annotation",
args: args{
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"appmesh.k8s.aws/sidecarEnvJson": `[{"DD_ENV":"prod","TEST_ENV":"env_val"},{"PROD_ENV":"prod_env"}]`,
},
},
},
},
want: map[string]string{
"DD_ENV": "prod",
"TEST_ENV": "env_val",
"PROD_ENV": "prod_env",
},
wantErr: nil,
},
{
name: "pods with no appmesh.k8s.aws/sidecarEnvJson annotation",
args: args{
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
},
},
},
want: map[string]string{},
wantErr: nil,
},
{
name: "pods with invalid appmesh.k8s.aws/sidecarEnvJson annotation",
args: args{
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"appmesh.k8s.aws/sidecarEnvJson": `[{"DD_ENV":"{PROD_ENV: "prod"}","TEST_ENV":"env_val"}]`,
},
},
},
},
wantErr: errors.New("malformed annotation appmesh.k8s.aws/sidecarEnvJson, expected format: [{\"DD_ENV\":\"prod\",\"TEST_ENV\":\"env_val\"}]"),
},
{
name: "pods with Nested Json appmesh.k8s.aws/sidecarEnvJson annotation",
args: args{
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"appmesh.k8s.aws/sidecarEnvJson": `[{"DD_ENV":{"PROD_ENV": "prod"},"TEST_ENV":"env_val"}]`,
},
},
},
},
wantErr: errors.New("nested json isn't supported with this annotation appmesh.k8s.aws/sidecarEnvJson, expected format: [{\"DD_ENV\":\"prod\",\"TEST_ENV\":\"env_val\"}]"),
},
{
name: "pods with no_input appmesh.k8s.aws/sidecarEnvJson annotation",
args: args{
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"appmesh.k8s.aws/sidecarEnvJson": ``,
},
},
},
},
wantErr: errors.New("malformed annotation appmesh.k8s.aws/sidecarEnvJson, expected format: [{\"DD_ENV\":\"prod\",\"TEST_ENV\":\"env_val\"}]"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
m := &envoyMutator{}
got, err := m.getCustomEnvJson(tt.args.pod)
if tt.wantErr != nil {
assert.EqualError(t, err, tt.wantErr.Error())
} else {
assert.NoError(t, err)
assert.Equal(t, got, tt.want)
}
})
}
}

func Test_envoyMutator_getAugmentedMeshName(t *testing.T) {
type fields struct {
Expand Down
Loading