diff --git a/kyaml/kio/filters/container.go b/kyaml/kio/filters/container.go index 40a7bfc6b..c3a60cf98 100644 --- a/kyaml/kio/filters/container.go +++ b/kyaml/kio/filters/container.go @@ -16,7 +16,7 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -// GrepFilter filters Resources using a container image. +// ContainerFilter filters Resources using a container image. // The container must start a process that reads the list of // input Resources from stdin, reads the Configuration from the env // API_CONFIG, and writes the filtered Resources to stdout. @@ -30,6 +30,9 @@ type ContainerFilter struct { // Image is the container image to use to create a container. Image string `yaml:"image,omitempty"` + // Network is the container network to use. + Network string `yaml:"network,omitempty"` + // Config is the API configuration for the container and passed through the // API_CONFIG env var to the container. // Typically a Kubernetes style Resource Config. @@ -86,12 +89,18 @@ func (c *ContainerFilter) getArgs() []string { // run the container using docker. this is simpler than using the docker // libraries, and ensures things like auth work the same as if the container // was run from the cli. + + network := "none" + if c.Network != "" { + network = c.Network + } + args := []string{"docker", "run", "--rm", // delete the container afterward "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr // added security options - "--network", "none", // disable the network + "--network", network, "--user", "nobody", // run as nobody // don't make fs readonly because things like heredoc rely on writing tmp files "--security-opt=no-new-privileges", // don't allow the user to escalate privileges diff --git a/kyaml/kio/filters/container_test.go b/kyaml/kio/filters/container_test.go index 0ce0ad73a..782033149 100644 --- a/kyaml/kio/filters/container_test.go +++ b/kyaml/kio/filters/container_test.go @@ -97,17 +97,41 @@ metadata: } expected = append(expected, "example.com:version") assert.Equal(t, expected, cmd.Args) +} - foundKyaml := false - for _, e := range cmd.Env { - // verify the command has the right environment variables to pass to the container - split := strings.Split(e, "=") - if split[0] == "KYAML_TEST" { - assert.Equal(t, "FOO", split[1]) - foundKyaml = true - } +func TestFilter_command_network(t *testing.T) { + cfg, err := yaml.Parse(`apiversion: apps/v1 +kind: Deployment +metadata: + name: foo +`) + if !assert.NoError(t, err) { + return } - assert.True(t, foundKyaml) + instance := &ContainerFilter{ + Image: "example.com:version", + Network: "test-net", + Config: cfg, + } + cmd, err := instance.getCommand() + if !assert.NoError(t, err) { + return + } + + expected := []string{ + "docker", "run", + "--rm", + "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", + "--network", "test-net", + "--user", "nobody", + "--security-opt=no-new-privileges", + } + for _, e := range os.Environ() { + // the process env + expected = append(expected, "-e", strings.Split(e, "=")[0]) + } + expected = append(expected, "example.com:version") + assert.Equal(t, expected, cmd.Args) } func TestFilter_Filter(t *testing.T) {