Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2d803afc
Commit
2d803afc
authored
Nov 29, 2016
by
Michael Fraenkel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ConfigMaps populate environment variables
parent
63eec960
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
424 additions
and
10 deletions
+424
-10
fuzzer.go
pkg/api/testing/fuzzer.go
+11
-0
types.go
pkg/api/types.go
+28
-0
types.go
pkg/api/v1/types.go
+28
-0
validation.go
pkg/api/validation/validation.go
+24
-0
validation_test.go
pkg/api/validation/validation_test.go
+59
-0
describe.go
pkg/kubectl/describe.go
+18
-0
describe_test.go
pkg/kubectl/describe_test.go
+11
-2
kubelet_pods.go
pkg/kubelet/kubelet_pods.go
+47
-4
kubelet_pods_test.go
pkg/kubelet/kubelet_pods_test.go
+144
-4
configmap.go
test/e2e/common/configmap.go
+54
-0
No files found.
pkg/api/testing/fuzzer.go
View file @
2d803afc
...
...
@@ -376,6 +376,17 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
ev
.
ValueFrom
.
FieldRef
.
FieldPath
=
c
.
RandString
()
}
},
func
(
ev
*
api
.
EnvFromSource
,
c
fuzz
.
Continue
)
{
if
c
.
RandBool
()
{
ev
.
Prefix
=
"p_"
}
if
c
.
RandBool
()
{
c
.
Fuzz
(
&
ev
.
ConfigMapRef
)
}
},
func
(
cm
*
api
.
ConfigMapEnvSource
,
c
fuzz
.
Continue
)
{
c
.
FuzzNoCustom
(
cm
)
// fuzz self without calling this function again
},
func
(
sc
*
api
.
SecurityContext
,
c
fuzz
.
Continue
)
{
c
.
FuzzNoCustom
(
sc
)
// fuzz self without calling this function again
if
c
.
RandBool
()
{
...
...
pkg/api/types.go
View file @
2d803afc
...
...
@@ -1133,6 +1133,26 @@ type SecretKeySelector struct {
Key
string
}
// EnvFromSource represents the source of a set of ConfigMaps
type
EnvFromSource
struct
{
// An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
// +optional
Prefix
string
// The ConfigMap to select from.
//+optional
ConfigMapRef
*
ConfigMapEnvSource
}
// ConfigMapEnvSource selects a ConfigMap to populate the environment
// variables with.
//
// The contents of the target ConfigMap's Data field will represent the
// key-value pairs as environment variables.
type
ConfigMapEnvSource
struct
{
// The ConfigMap to select from.
LocalObjectReference
}
// HTTPHeader describes a custom header to be used in HTTP probes
type
HTTPHeader
struct
{
// The header field name
...
...
@@ -1274,6 +1294,14 @@ type Container struct {
WorkingDir
string
// +optional
Ports
[]
ContainerPort
// List of sources to populate environment variables in the container.
// The keys defined within a source must be a C_IDENTIFIER. An invalid key
// will prevent the container from starting. When a key exists in multiple
// sources, the value associated with the last source will take precedence.
// Values defined by an Env with a duplicate key will take precedence.
// Cannot be updated.
// +optional
EnvFrom
[]
EnvFromSource
// +optional
Env
[]
EnvVar
// Compute resource requirements.
...
...
pkg/api/v1/types.go
View file @
2d803afc
...
...
@@ -1233,6 +1233,26 @@ type SecretKeySelector struct {
Key
string
`json:"key" protobuf:"bytes,2,opt,name=key"`
}
// EnvFromSource represents the source of a set of ConfigMaps
type
EnvFromSource
struct
{
// An optional identifer to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
// +optional
Prefix
string
`json:"prefix,omitempty" protobuf:"bytes,1,opt,name=prefix"`
// The ConfigMap to select from
// +optional
ConfigMapRef
*
ConfigMapEnvSource
`json:"configMapRef,omitempty" protobuf:"bytes,2,opt,name=configMapRef"`
}
// ConfigMapEnvSource selects a ConfigMap to populate the environment
// variables with.
//
// The contents of the target ConfigMap's Data field will represent the
// key-value pairs as environment variables.
type
ConfigMapEnvSource
struct
{
// The ConfigMap to select from.
LocalObjectReference
`json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
}
// HTTPHeader describes a custom header to be used in HTTP probes
type
HTTPHeader
struct
{
// The header field name
...
...
@@ -1409,6 +1429,14 @@ type Container struct {
// Cannot be updated.
// +optional
Ports
[]
ContainerPort
`json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"`
// List of sources to populate environment variables in the container.
// The keys defined within a source must be a C_IDENTIFIER. An invalid key
// will prevent the container from starting. When a key exists in multiple
// sources, the value associated with the last source will take precedence.
// Values defined by an Env with a duplicate key will take precedence.
// Cannot be updated.
// +optional
EnvFrom
[]
EnvFromSource
`json:"envFrom,omitempty" protobuf:"bytes,19,rep,name=envFrom"`
// List of environment variables to set in the container.
// Cannot be updated.
// +optional
...
...
pkg/api/validation/validation.go
View file @
2d803afc
...
...
@@ -1435,6 +1435,30 @@ func validateContainerResourceFieldSelector(fs *api.ResourceFieldSelector, expre
return
allErrs
}
func
validateEnvFrom
(
vars
[]
api
.
EnvFromSource
,
fldPath
*
field
.
Path
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
for
i
,
ev
:=
range
vars
{
idxPath
:=
fldPath
.
Index
(
i
)
if
len
(
ev
.
Prefix
)
>
0
{
for
_
,
msg
:=
range
validation
.
IsCIdentifier
(
ev
.
Prefix
)
{
allErrs
=
append
(
allErrs
,
field
.
Invalid
(
idxPath
.
Child
(
"prefix"
),
ev
.
Prefix
,
msg
))
}
}
if
ev
.
ConfigMapRef
!=
nil
{
allErrs
=
append
(
allErrs
,
validateConfigMapEnvSource
(
ev
.
ConfigMapRef
,
idxPath
.
Child
(
"configMapRef"
))
...
)
}
}
return
allErrs
}
func
validateConfigMapEnvSource
(
configMapSource
*
api
.
ConfigMapEnvSource
,
fldPath
*
field
.
Path
)
field
.
ErrorList
{
allErrs
:=
field
.
ErrorList
{}
if
len
(
configMapSource
.
Name
)
==
0
{
allErrs
=
append
(
allErrs
,
field
.
Required
(
fldPath
.
Child
(
"name"
),
""
))
}
return
allErrs
}
var
validContainerResourceDivisorForCPU
=
sets
.
NewString
(
"1m"
,
"1"
)
var
validContainerResourceDivisorForMemory
=
sets
.
NewString
(
"1"
,
"1k"
,
"1M"
,
"1G"
,
"1T"
,
"1P"
,
"1E"
,
"1Ki"
,
"1Mi"
,
"1Gi"
,
"1Ti"
,
"1Pi"
,
"1Ei"
)
...
...
pkg/api/validation/validation_test.go
View file @
2d803afc
...
...
@@ -2719,6 +2719,65 @@ func TestValidateEnv(t *testing.T) {
}
}
func
TestValidateEnvFrom
(
t
*
testing
.
T
)
{
successCase
:=
[]
api
.
EnvFromSource
{
{
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"abc"
},
},
},
{
Prefix
:
"pre_"
,
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"abc"
},
},
},
}
if
errs
:=
validateEnvFrom
(
successCase
,
field
.
NewPath
(
"field"
));
len
(
errs
)
!=
0
{
t
.
Errorf
(
"expected success: %v"
,
errs
)
}
errorCases
:=
[]
struct
{
name
string
envs
[]
api
.
EnvFromSource
expectedError
string
}{
{
name
:
"zero-length name"
,
envs
:
[]
api
.
EnvFromSource
{
{
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
""
}},
},
},
expectedError
:
"field[0].configMapRef.name: Required value"
,
},
{
name
:
"invalid prefix"
,
envs
:
[]
api
.
EnvFromSource
{
{
Prefix
:
"a.b"
,
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"abc"
}},
},
},
expectedError
:
`field[0].prefix: Invalid value: "a.b": `
+
idErrMsg
,
},
}
for
_
,
tc
:=
range
errorCases
{
if
errs
:=
validateEnvFrom
(
tc
.
envs
,
field
.
NewPath
(
"field"
));
len
(
errs
)
==
0
{
t
.
Errorf
(
"expected failure for %s"
,
tc
.
name
)
}
else
{
for
i
:=
range
errs
{
str
:=
errs
[
i
]
.
Error
()
if
str
!=
""
&&
!
strings
.
Contains
(
str
,
tc
.
expectedError
)
{
t
.
Errorf
(
"%s: expected error detail either empty or %q, got %q"
,
tc
.
name
,
tc
.
expectedError
,
str
)
}
}
}
}
}
func
TestValidateVolumeMounts
(
t
*
testing
.
T
)
{
volumes
:=
sets
.
NewString
(
"abc"
,
"123"
,
"abc-123"
)
...
...
pkg/kubectl/describe.go
View file @
2d803afc
...
...
@@ -890,6 +890,7 @@ func describeContainers(label string, containers []api.Container, containerStatu
}
describeContainerProbe
(
container
,
w
)
describeContainerVolumes
(
container
,
w
)
describeContainerEnvFrom
(
container
,
resolverFn
,
w
)
describeContainerEnvVars
(
container
,
resolverFn
,
w
)
}
}
...
...
@@ -1012,6 +1013,7 @@ func describeContainerEnvVars(container api.Container, resolverFn EnvVarResolver
none
=
"
\t
<none>"
}
w
.
Write
(
LEVEL_2
,
"Environment Variables:%s
\n
"
,
none
)
for
_
,
e
:=
range
container
.
Env
{
if
e
.
ValueFrom
==
nil
{
w
.
Write
(
LEVEL_3
,
"%s:
\t
%s
\n
"
,
e
.
Name
,
e
.
Value
)
...
...
@@ -1043,6 +1045,22 @@ func describeContainerEnvVars(container api.Container, resolverFn EnvVarResolver
}
}
func
describeContainerEnvFrom
(
container
api
.
Container
,
resolverFn
EnvVarResolverFunc
,
w
*
PrefixWriter
)
{
none
:=
""
if
len
(
container
.
EnvFrom
)
==
0
{
none
=
"
\t
<none>"
}
w
.
Write
(
LEVEL_2
,
"Environment Variables from:%s
\n
"
,
none
)
for
_
,
e
:=
range
container
.
EnvFrom
{
if
len
(
e
.
Prefix
)
==
0
{
w
.
Write
(
LEVEL_3
,
"%s
\t
ConfigMap
\n
"
,
e
.
ConfigMapRef
.
Name
)
}
else
{
w
.
Write
(
LEVEL_3
,
"%s
\t
ConfigMap with prefix '%s'
\n
"
,
e
.
ConfigMapRef
.
Name
,
e
.
Prefix
)
}
}
}
// DescribeProbe is exported for consumers in other API groups that have probes
func
DescribeProbe
(
probe
*
api
.
Probe
)
string
{
attrs
:=
fmt
.
Sprintf
(
"delay=%ds timeout=%ds period=%ds #success=%d #failure=%d"
,
probe
.
InitialDelaySeconds
,
probe
.
TimeoutSeconds
,
probe
.
PeriodSeconds
,
probe
.
SuccessThreshold
,
probe
.
FailureThreshold
)
...
...
pkg/kubectl/describe_test.go
View file @
2d803afc
...
...
@@ -288,13 +288,22 @@ func TestDescribeContainers(t *testing.T) {
},
// Env
{
container
:
api
.
Container
{
Name
:
"test"
,
Image
:
"image"
,
Env
:
[]
api
.
EnvVar
{{
Name
:
"envname"
,
Value
:
"xyz"
}}},
container
:
api
.
Container
{
Name
:
"test"
,
Image
:
"image"
,
Env
:
[]
api
.
EnvVar
{{
Name
:
"envname"
,
Value
:
"xyz"
}}
,
EnvFrom
:
[]
api
.
EnvFromSource
{{
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"a123"
}}}}
},
status
:
api
.
ContainerStatus
{
Name
:
"test"
,
Ready
:
true
,
RestartCount
:
7
,
},
expectedElements
:
[]
string
{
"test"
,
"State"
,
"Waiting"
,
"Ready"
,
"True"
,
"Restart Count"
,
"7"
,
"Image"
,
"image"
,
"envname"
,
"xyz"
},
expectedElements
:
[]
string
{
"test"
,
"State"
,
"Waiting"
,
"Ready"
,
"True"
,
"Restart Count"
,
"7"
,
"Image"
,
"image"
,
"envname"
,
"xyz"
,
"a123
\t
ConfigMap"
},
},
{
container
:
api
.
Container
{
Name
:
"test"
,
Image
:
"image"
,
Env
:
[]
api
.
EnvVar
{{
Name
:
"envname"
,
Value
:
"xyz"
}},
EnvFrom
:
[]
api
.
EnvFromSource
{{
Prefix
:
"p_"
,
ConfigMapRef
:
&
api
.
ConfigMapEnvSource
{
LocalObjectReference
:
api
.
LocalObjectReference
{
Name
:
"a123"
}}}}},
status
:
api
.
ContainerStatus
{
Name
:
"test"
,
Ready
:
true
,
RestartCount
:
7
,
},
expectedElements
:
[]
string
{
"test"
,
"State"
,
"Waiting"
,
"Ready"
,
"True"
,
"Restart Count"
,
"7"
,
"Image"
,
"image"
,
"envname"
,
"xyz"
,
"a123
\t
ConfigMap with prefix 'p_'"
},
},
// Command
{
...
...
pkg/kubelet/kubelet_pods.go
View file @
2d803afc
...
...
@@ -414,6 +414,47 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
return
result
,
err
}
var
(
configMaps
=
make
(
map
[
string
]
*
v1
.
ConfigMap
)
tmpEnv
=
make
(
map
[
string
]
string
)
)
// Env will override EnvFrom variables.
// Process EnvFrom first then allow Env to replace existing values.
for
_
,
envFrom
:=
range
container
.
EnvFrom
{
if
envFrom
.
ConfigMapRef
!=
nil
{
name
:=
envFrom
.
ConfigMapRef
.
Name
configMap
,
ok
:=
configMaps
[
name
]
if
!
ok
{
if
kl
.
kubeClient
==
nil
{
return
result
,
fmt
.
Errorf
(
"Couldn't get configMap %v/%v, no kubeClient defined"
,
pod
.
Namespace
,
name
)
}
configMap
,
err
=
kl
.
kubeClient
.
Core
()
.
ConfigMaps
(
pod
.
Namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
return
result
,
err
}
configMaps
[
name
]
=
configMap
}
for
k
,
v
:=
range
configMap
.
Data
{
if
errMsgs
:=
utilvalidation
.
IsCIdentifier
(
k
);
len
(
errMsgs
)
!=
0
{
return
result
,
fmt
.
Errorf
(
"Invalid environment variable name, %v, from configmap %v/%v: %s"
,
k
,
pod
.
Namespace
,
name
,
errMsgs
[
0
])
}
if
len
(
envFrom
.
Prefix
)
>
0
{
k
=
envFrom
.
Prefix
+
k
}
// Accesses apiserver+Pods.
// So, the master may set service env vars, or kubelet may. In case both are doing
// it, we delete the key from the kubelet-generated ones so we don't have duplicate
// env vars.
// TODO: remove this next line once all platforms use apiserver+Pods.
delete
(
serviceEnv
,
k
)
tmpEnv
[
k
]
=
v
}
}
}
// Determine the final values of variables:
//
// 1. Determine the final value of each variable:
...
...
@@ -424,8 +465,6 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
// 2. Create the container's environment in the order variables are declared
// 3. Add remaining service environment vars
var
(
tmpEnv
=
make
(
map
[
string
]
string
)
configMaps
=
make
(
map
[
string
]
*
v1
.
ConfigMap
)
secrets
=
make
(
map
[
string
]
*
v1
.
Secret
)
mappingFunc
=
expansion
.
MappingFuncFor
(
tmpEnv
,
serviceEnv
)
)
...
...
@@ -434,7 +473,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
// So, the master may set service env vars, or kubelet may. In case both are doing
// it, we delete the key from the kubelet-generated ones so we don't have duplicate
// env vars.
// TODO: remove this net line once all platforms use apiserver+Pods.
// TODO: remove this ne
x
t line once all platforms use apiserver+Pods.
delete
(
serviceEnv
,
envVar
.
Name
)
runtimeVal
:=
envVar
.
Value
...
...
@@ -499,7 +538,11 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
}
tmpEnv
[
envVar
.
Name
]
=
runtimeVal
result
=
append
(
result
,
kubecontainer
.
EnvVar
{
Name
:
envVar
.
Name
,
Value
:
tmpEnv
[
envVar
.
Name
]})
}
// Append the env vars
for
k
,
v
:=
range
tmpEnv
{
result
=
append
(
result
,
kubecontainer
.
EnvVar
{
Name
:
k
,
Value
:
v
})
}
// Append remaining service env vars.
...
...
pkg/kubelet/kubelet_pods_test.go
View file @
2d803afc
...
...
@@ -268,7 +268,9 @@ func TestMakeEnvironmentVariables(t *testing.T) {
container
*
v1
.
Container
// the container to use
masterServiceNs
string
// the namespace to read master service info from
nilLister
bool
// whether the lister should be nil
configMap
*
v1
.
ConfigMap
// an optional ConfigMap to pull from
expectedEnvs
[]
kubecontainer
.
EnvVar
// a set of expected environment vars
expectedError
bool
// does the test fail
}{
{
name
:
"api server = Y, kubelet = Y"
,
...
...
@@ -605,6 +607,132 @@ func TestMakeEnvironmentVariables(t *testing.T) {
},
},
},
{
name
:
"configmap"
,
ns
:
"test1"
,
container
:
&
v1
.
Container
{
EnvFrom
:
[]
v1
.
EnvFromSource
{
{
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
"test-config-map"
}},
},
{
Prefix
:
"p_"
,
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
"test-config-map"
}},
},
},
Env
:
[]
v1
.
EnvVar
{
{
Name
:
"TEST_LITERAL"
,
Value
:
"test-test-test"
,
},
{
Name
:
"EXPANSION_TEST"
,
Value
:
"$(REPLACE_ME)"
,
},
{
Name
:
"DUPE_TEST"
,
Value
:
"ENV_VAR"
,
},
},
},
masterServiceNs
:
"nothing"
,
nilLister
:
false
,
configMap
:
&
v1
.
ConfigMap
{
ObjectMeta
:
v1
.
ObjectMeta
{
Namespace
:
"test1"
,
Name
:
"test-configmap"
,
},
Data
:
map
[
string
]
string
{
"REPLACE_ME"
:
"FROM_CONFIG_MAP"
,
"DUPE_TEST"
:
"CONFIG_MAP"
,
},
},
expectedEnvs
:
[]
kubecontainer
.
EnvVar
{
{
Name
:
"TEST_LITERAL"
,
Value
:
"test-test-test"
,
},
{
Name
:
"TEST_SERVICE_HOST"
,
Value
:
"1.2.3.3"
,
},
{
Name
:
"TEST_SERVICE_PORT"
,
Value
:
"8083"
,
},
{
Name
:
"TEST_PORT"
,
Value
:
"tcp://1.2.3.3:8083"
,
},
{
Name
:
"TEST_PORT_8083_TCP"
,
Value
:
"tcp://1.2.3.3:8083"
,
},
{
Name
:
"TEST_PORT_8083_TCP_PROTO"
,
Value
:
"tcp"
,
},
{
Name
:
"TEST_PORT_8083_TCP_PORT"
,
Value
:
"8083"
,
},
{
Name
:
"TEST_PORT_8083_TCP_ADDR"
,
Value
:
"1.2.3.3"
,
},
{
Name
:
"REPLACE_ME"
,
Value
:
"FROM_CONFIG_MAP"
,
},
{
Name
:
"EXPANSION_TEST"
,
Value
:
"FROM_CONFIG_MAP"
,
},
{
Name
:
"DUPE_TEST"
,
Value
:
"ENV_VAR"
,
},
{
Name
:
"p_REPLACE_ME"
,
Value
:
"FROM_CONFIG_MAP"
,
},
{
Name
:
"p_DUPE_TEST"
,
Value
:
"CONFIG_MAP"
,
},
},
},
{
name
:
"configmap_missing"
,
ns
:
"test1"
,
container
:
&
v1
.
Container
{
EnvFrom
:
[]
v1
.
EnvFromSource
{
{
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
"test-config-map"
}}},
},
},
masterServiceNs
:
"nothing"
,
expectedError
:
true
,
},
{
name
:
"configmap_invalid_keys"
,
ns
:
"test1"
,
container
:
&
v1
.
Container
{
EnvFrom
:
[]
v1
.
EnvFromSource
{
{
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
"test-config-map"
}}},
},
},
masterServiceNs
:
"nothing"
,
configMap
:
&
v1
.
ConfigMap
{
ObjectMeta
:
v1
.
ObjectMeta
{
Namespace
:
"test1"
,
Name
:
"test-configmap"
,
},
Data
:
map
[
string
]
string
{
"-1234"
:
"abc"
,
},
},
expectedError
:
true
,
},
}
for
_
,
tc
:=
range
testCases
{
...
...
@@ -617,6 +745,14 @@ func TestMakeEnvironmentVariables(t *testing.T) {
kl
.
serviceLister
=
testServiceLister
{
services
}
}
testKubelet
.
fakeKubeClient
.
AddReactor
(
"get"
,
"configmaps"
,
func
(
action
core
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
var
err
error
if
tc
.
configMap
==
nil
{
err
=
errors
.
New
(
"no configmap defined"
)
}
return
true
,
tc
.
configMap
,
err
})
testPod
:=
&
v1
.
Pod
{
ObjectMeta
:
v1
.
ObjectMeta
{
Namespace
:
tc
.
ns
,
...
...
@@ -630,11 +766,15 @@ func TestMakeEnvironmentVariables(t *testing.T) {
podIP
:=
"1.2.3.4"
result
,
err
:=
kl
.
makeEnvironmentVariables
(
testPod
,
tc
.
container
,
podIP
)
assert
.
NoError
(
t
,
err
,
"[%s]"
,
tc
.
name
)
if
tc
.
expectedError
{
assert
.
Error
(
t
,
err
,
tc
.
name
)
}
else
{
assert
.
NoError
(
t
,
err
,
"[%s]"
,
tc
.
name
)
sort
.
Sort
(
envs
(
result
))
sort
.
Sort
(
envs
(
tc
.
expectedEnvs
))
assert
.
Equal
(
t
,
tc
.
expectedEnvs
,
result
,
"[%s] env entries"
,
tc
.
name
)
sort
.
Sort
(
envs
(
result
))
sort
.
Sort
(
envs
(
tc
.
expectedEnvs
))
assert
.
Equal
(
t
,
tc
.
expectedEnvs
,
result
,
"[%s] env entries"
,
tc
.
name
)
}
}
}
...
...
test/e2e/common/configmap.go
View file @
2d803afc
...
...
@@ -196,6 +196,46 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
})
})
It
(
"should be consumable via the environment [Conformance]"
,
func
()
{
name
:=
"configmap-test-"
+
string
(
uuid
.
NewUUID
())
configMap
:=
newEnvFromConfigMap
(
f
,
name
)
By
(
fmt
.
Sprintf
(
"Creating configMap %v/%v"
,
f
.
Namespace
.
Name
,
configMap
.
Name
))
var
err
error
if
configMap
,
err
=
f
.
ClientSet
.
Core
()
.
ConfigMaps
(
f
.
Namespace
.
Name
)
.
Create
(
configMap
);
err
!=
nil
{
framework
.
Failf
(
"unable to create test configMap %s: %v"
,
configMap
.
Name
,
err
)
}
pod
:=
&
v1
.
Pod
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
"pod-configmaps-"
+
string
(
uuid
.
NewUUID
()),
},
Spec
:
v1
.
PodSpec
{
Containers
:
[]
v1
.
Container
{
{
Name
:
"env-test"
,
Image
:
"gcr.io/google_containers/busybox:1.24"
,
Command
:
[]
string
{
"sh"
,
"-c"
,
"env"
},
EnvFrom
:
[]
v1
.
EnvFromSource
{
{
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
name
}},
},
{
Prefix
:
"p_"
,
ConfigMapRef
:
&
v1
.
ConfigMapEnvSource
{
LocalObjectReference
:
v1
.
LocalObjectReference
{
Name
:
name
}},
},
},
},
},
RestartPolicy
:
v1
.
RestartPolicyNever
,
},
}
f
.
TestContainerOutput
(
"consume configMaps"
,
pod
,
0
,
[]
string
{
"data_1=value-1"
,
"data_2=value-2"
,
"data_3=value-3"
,
"p_data_1=value-1"
,
"p_data_2=value-2"
,
"p_data_3=value-3"
,
})
})
It
(
"should be consumable in multiple volumes in the same pod [Conformance]"
,
func
()
{
var
(
name
=
"configmap-test-volume-"
+
string
(
uuid
.
NewUUID
())
...
...
@@ -283,6 +323,20 @@ func newConfigMap(f *framework.Framework, name string) *v1.ConfigMap {
}
}
func
newEnvFromConfigMap
(
f
*
framework
.
Framework
,
name
string
)
*
v1
.
ConfigMap
{
return
&
v1
.
ConfigMap
{
ObjectMeta
:
v1
.
ObjectMeta
{
Namespace
:
f
.
Namespace
.
Name
,
Name
:
name
,
},
Data
:
map
[
string
]
string
{
"data_1"
:
"value-1"
,
"data_2"
:
"value-2"
,
"data_3"
:
"value-3"
,
},
}
}
func
doConfigMapE2EWithoutMappings
(
f
*
framework
.
Framework
,
uid
,
fsGroup
int64
,
defaultMode
*
int32
)
{
var
(
name
=
"configmap-test-volume-"
+
string
(
uuid
.
NewUUID
())
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment