-
Notifications
You must be signed in to change notification settings - Fork 706
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial helm post renderer. (#1670)
* Add initial helm post renderer. * Simplify error check in test. * Switch to yaml.v2
- Loading branch information
1 parent
17d1f42
commit 3f3f76a
Showing
2 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package agent | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
|
||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// DockerSecretsPostRenderer is a helm post-renderer (see https://helm.sh/docs/topics/advanced/#post-rendering) | ||
// which appends image pull secrets to container images which match specified registry domains. | ||
type DockerSecretsPostRenderer struct { | ||
// secrets maps a registry domain to a single secret to be used for that domain. | ||
secrets map[string]string | ||
} | ||
|
||
// NewDockerSecretsPostRenderer returns a post renderer configured with the specified secrets. | ||
func NewDockerSecretsPostRenderer(secrets map[string]string) *DockerSecretsPostRenderer { | ||
return &DockerSecretsPostRenderer{secrets} | ||
} | ||
|
||
// Run returns the rendered yaml including any additions of the post-renderer. | ||
func (r *DockerSecretsPostRenderer) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) { | ||
if r.secrets == nil { | ||
return renderedManifests, nil | ||
} | ||
|
||
decoder := yaml.NewDecoder(renderedManifests) | ||
var resourceList []interface{} | ||
for { | ||
var resource interface{} | ||
err := decoder.Decode(&resource) | ||
if err == io.EOF { | ||
break | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
resourceList = append(resourceList, resource) | ||
} | ||
|
||
// TODO: Update relevant container images with image pull secrets | ||
|
||
modifiedManifests = bytes.NewBuffer([]byte{}) | ||
encoder := yaml.NewEncoder(modifiedManifests) | ||
defer encoder.Close() | ||
|
||
for _, resource := range resourceList { | ||
err = encoder.Encode(resource) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return modifiedManifests, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package agent | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
) | ||
|
||
func TestDockerSecretsPostRenderer(t *testing.T) { | ||
testCases := []struct { | ||
name string | ||
input *bytes.Buffer | ||
secrets map[string]string | ||
output *bytes.Buffer | ||
expectErr bool | ||
}{ | ||
{ | ||
name: "it returns the input without parsing when no secrets set", | ||
input: bytes.NewBuffer([]byte(`anything at : all`)), | ||
output: bytes.NewBuffer([]byte(`anything at : all`)), | ||
}, | ||
{ | ||
name: "it returns an error if the input cannot be parsed as yaml", | ||
input: bytes.NewBuffer([]byte("v: [A,")), | ||
secrets: map[string]string{"foo.example.com": "secret-name"}, | ||
expectErr: true, | ||
}, | ||
{ | ||
name: "it re-renders the yaml with ordering and indent changes only", | ||
input: bytes.NewBuffer([]byte(`apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: image-secret-test | ||
annotations: | ||
annotation-1: some-annotation | ||
spec: | ||
containers: | ||
- command: | ||
- sh | ||
- -c | ||
- echo 'foo' | ||
env: | ||
- name: SOME_ENV | ||
value: env_value | ||
image: example.com/bitnami/nginx:1.16.1-debian-10-r42 | ||
name: container-name | ||
restartPolicy: Never | ||
--- | ||
other: doc | ||
`)), | ||
output: bytes.NewBuffer([]byte(`apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
annotations: | ||
annotation-1: some-annotation | ||
name: image-secret-test | ||
spec: | ||
containers: | ||
- command: | ||
- sh | ||
- -c | ||
- echo 'foo' | ||
env: | ||
- name: SOME_ENV | ||
value: env_value | ||
image: example.com/bitnami/nginx:1.16.1-debian-10-r42 | ||
name: container-name | ||
restartPolicy: Never | ||
--- | ||
other: doc | ||
`)), | ||
secrets: map[string]string{"foo.example.com": "secret-name"}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
r := NewDockerSecretsPostRenderer(tc.secrets) | ||
|
||
renderedManifests, err := r.Run(tc.input) | ||
if got, want := err != nil, tc.expectErr; got != want { | ||
t.Fatalf("got: %t, want: %t. err: %+v", got, want, err) | ||
} | ||
|
||
if got, want := renderedManifests.String(), tc.output.String(); !cmp.Equal(got, want) { | ||
t.Errorf("mismatch (-want +got):\n%s", cmp.Diff(want, got)) | ||
} | ||
}) | ||
} | ||
} |