Change network to a boolean

This commit is contained in:
Donny Xia
2020-09-16 16:20:50 -07:00
parent 76bae738a0
commit f6c06b58ef
6 changed files with 129 additions and 43 deletions

View File

@@ -154,13 +154,17 @@ func (c *Filter) setupExec() {
// getArgs returns the command + args to run to spawn the container // getArgs returns the command + args to run to spawn the container
func (c *Filter) getCommand() (string, []string) { func (c *Filter) getCommand() (string, []string) {
network := runtimeutil.NetworkNameNone
if c.ContainerSpec.Network {
network = runtimeutil.NetworkNameHost
}
// run the container using docker. this is simpler than using the docker // 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 // libraries, and ensures things like auth work the same as if the container
// was run from the cli. // was run from the cli.
args := []string{"run", args := []string{"run",
"--rm", // delete the container afterward "--rm", // delete the container afterward
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr
"--network", string(c.ContainerSpec.Network.Name), "--network", string(network),
// added security options // added security options
"--user", c.User.String(), "--user", c.User.String(),
@@ -186,10 +190,5 @@ func NewContainer(spec runtimeutil.ContainerSpec) Filter {
f.ContainerSpec.User = runtimeutil.UserNobody f.ContainerSpec.User = runtimeutil.UserNobody
} }
// default network name is none
if f.ContainerSpec.Network.Name == "" {
f.ContainerSpec.Network.Name = runtimeutil.NetworkNameNone
}
return f return f
} }

View File

@@ -55,17 +55,15 @@ metadata:
"run", "run",
"--rm", "--rm",
"-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR",
"--network", "test-1", "--network", "host",
"--user", "nobody", "--user", "nobody",
"--security-opt=no-new-privileges", "--security-opt=no-new-privileges",
}, },
instance: NewContainer( instance: NewContainer(
runtimeutil.ContainerSpec{ runtimeutil.ContainerSpec{
Image: "example.com:version", Image: "example.com:version",
Network: runtimeutil.ContainerNetwork{ Network: true,
Name: "test-1", User: "nobody",
},
User: "nobody",
}, },
), ),
}, },

View File

@@ -38,8 +38,8 @@ const (
type ContainerNetworkName string type ContainerNetworkName string
const ( const (
NetworkNameNone ContainerNetworkName = "none" NetworkNameNone ContainerNetworkName = "none"
NetworkNameEmpty ContainerNetworkName = "" NetworkNameHost ContainerNetworkName = "host"
) )
const defaultEnvValue string = "true" const defaultEnvValue string = "true"
@@ -166,7 +166,7 @@ type ContainerSpec struct {
Image string `json:"image,omitempty" yaml:"image,omitempty"` Image string `json:"image,omitempty" yaml:"image,omitempty"`
// Network defines network specific configuration // Network defines network specific configuration
Network ContainerNetwork `json:"network,omitempty" yaml:"network,omitempty"` Network bool `json:"network,omitempty" yaml:"network,omitempty"`
// Mounts are the storage or directories to mount into the container // Mounts are the storage or directories to mount into the container
StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"` StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"`
@@ -178,15 +178,6 @@ type ContainerSpec struct {
Env []string `json:"envs,omitempty" yaml:"envs,omitempty"` Env []string `json:"envs,omitempty" yaml:"envs,omitempty"`
} }
// ContainerNetwork
type ContainerNetwork struct {
// Required specifies that function requires a network
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
// Name is the name of the network to use from a container
Name ContainerNetworkName `json:"name,omitempty" yaml:"name,omitempty"`
}
// StarlarkSpec defines how to run a function as a starlark program // StarlarkSpec defines how to run a function as a starlark program
type StarlarkSpec struct { type StarlarkSpec struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"`
@@ -237,7 +228,6 @@ func GetFunctionSpec(n *yaml.RNode) *FunctionSpec {
} }
if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil { if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil {
fn.Container.Network.Name = NetworkNameEmpty
fn.StorageMounts = []StorageMount{} fn.StorageMounts = []StorageMount{}
return fn return fn
} }

View File

@@ -1208,14 +1208,12 @@ metadata:
config.kubernetes.io/function: |- config.kubernetes.io/function: |-
container: container:
image: foo:v1.0.0 image: foo:v1.0.0
network: network: true
required: true
`, `,
expectedFn: ` expectedFn: `
container: container:
image: foo:v1.0.0 image: foo:v1.0.0
network: network: true
required: true
`, `,
}, },
@@ -1324,8 +1322,7 @@ metadata:
configFn: configFn:
container: container:
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0 image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
network: network: true
required: true
`, `,
required: true, required: true,
}, },
@@ -1337,8 +1334,7 @@ metadata:
configFn: configFn:
container: container:
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0 image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
network: network: false
required: false
`, `,
required: false, required: false,
}, },
@@ -1363,8 +1359,7 @@ metadata:
config.kubernetes.io/function: | config.kubernetes.io/function: |
container: container:
image: gcr.io/kustomize-functions/example-tshirt:v0.1.0 image: gcr.io/kustomize-functions/example-tshirt:v0.1.0
network: network: true
required: true
`, `,
required: true, required: true,
}, },
@@ -1376,7 +1371,7 @@ metadata:
return return
} }
fn := GetFunctionSpec(cfg) fn := GetFunctionSpec(cfg)
assert.Equal(t, tc.required, fn.Container.Network.Required) assert.Equal(t, tc.required, fn.Container.Network)
} }
} }

View File

@@ -294,12 +294,13 @@ func (r RunFns) getFunctionFilters(global bool, fns ...*yaml.RNode) (
for i := range fns { for i := range fns {
api := fns[i] api := fns[i]
spec := runtimeutil.GetFunctionSpec(api) spec := runtimeutil.GetFunctionSpec(api)
if spec.Container.Network.Required { if spec == nil {
if !r.Network { // resource doesn't have function spec
// TODO(eddiezane): Provide error info about which function needs the network continue
return fltrs, errors.Errorf("network required but not enabled with --network") }
} if spec.Container.Network && !r.Network {
spec.Container.Network.Name = runtimeutil.ContainerNetworkName(r.NetworkName) // TODO(eddiezane): Provide error info about which function needs the network
return fltrs, errors.Errorf("network required but not enabled with --network")
} }
// command line username and envs has higher priority // command line username and envs has higher priority
if !r.User.IsEmpty() { if !r.User.IsEmpty() {

View File

@@ -244,6 +244,17 @@ metadata:
out: []string{"gcr.io/example.com/image:v1.0.0"}, out: []string{"gcr.io/example.com/image:v1.0.0"},
}, },
{name: "no function spec",
in: []f{
{
explicitFunction: true,
value: `
foo: bar
`,
},
},
},
// Test // Test
// //
// //
@@ -685,6 +696,98 @@ metadata:
} }
} }
func TestRunFns_network(t *testing.T) {
tests := []struct {
name string
input string
network bool
expectNetwork bool
error string
}{
{
name: "imperative false, declarative false",
input: `
metadata:
annotations:
config.kubernetes.io/function: |
container:
image: a
network: false
`,
network: false,
expectNetwork: false,
},
{
name: "imperative true, declarative false",
input: `
metadata:
annotations:
config.kubernetes.io/function: |
container:
image: a
network: false
`,
network: true,
expectNetwork: false,
},
{
name: "imperative true, declarative true",
input: `
metadata:
annotations:
config.kubernetes.io/function: |
container:
image: a
network: true
`,
network: true,
expectNetwork: true,
},
{
name: "imperative false, declarative true",
input: `
metadata:
annotations:
config.kubernetes.io/function: |
container:
image: a
network: true
`,
network: false,
error: "network required but not enabled with --network",
},
}
for i := range tests {
tt := tests[i]
fn := yaml.MustParse(tt.input)
t.Run(tt.name, func(t *testing.T) {
// init the instance
r := &RunFns{
Functions: []*yaml.RNode{fn},
Network: tt.network,
}
r.init()
_, fltrs, _, err := r.getNodesAndFilters()
if tt.error != "" {
if !assert.EqualError(t, err, tt.error) {
t.FailNow()
}
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
fltr := fltrs[0].(*container.Filter)
if !assert.Equal(t, tt.expectNetwork, fltr.Network) {
t.FailNow()
}
})
}
}
func TestCmd_Execute(t *testing.T) { func TestCmd_Execute(t *testing.T) {
dir := setupTest(t) dir := setupTest(t)
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
@@ -987,7 +1090,7 @@ func getFilterProvider(t *testing.T) func(runtimeutil.FunctionSpec, *yaml.RNode)
} }
} }
func TestRunfns_mergeContainerEnv(t *testing.T) { func TestRunFns_mergeContainerEnv(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
instance RunFns instance RunFns