diff --git a/examples/downward-api/README.md b/examples/downward-api/README.md new file mode 100644 index 00000000000..8328f6fba5e --- /dev/null +++ b/examples/downward-api/README.md @@ -0,0 +1,33 @@ +# Downward API example + +Following this example, you will create a pod with a containers that consumes the pod's name and +namespace using the downward API. + +## Step Zero: Prerequisites + +This example assumes you have a Kubernetes cluster installed and running, and that you have +installed the ```kubectl``` command line tool somewhere in your path. Please see the [getting +started](../../docs/getting-started-guides) for installation instructions for your platform. + +## Step One: Create the pod + +Containers consume the downward API using environment variables. The downward API allows +containers to be injected with the name and namespace of the pod the container is in. + +Use the `examples/secrets/secret-pod.yaml` file to create a Pod with a container that consumes the +downward API. + +```shell +$ kubectl create -f examples/downward-api/dapi-pod.yaml +``` + +### Examine the logs + +This pod runs the `env` command in a container that consumes the downward API. You can grep +through the pod logs to see that the pod was injected with the correct values: + +```shell +$ kubectl log dapi-test-pod | grep POD_ +2015-04-30T20:22:18.568024817Z POD_NAME=dapi-test-pod +2015-04-30T20:22:18.568087688Z POD_NAMESPACE=default +``` diff --git a/examples/downward-api/dapi-pod.yaml b/examples/downward-api/dapi-pod.yaml new file mode 100644 index 00000000000..09e8bbe8c17 --- /dev/null +++ b/examples/downward-api/dapi-pod.yaml @@ -0,0 +1,19 @@ +apiVersion: v1beta3 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: gcr.io/google_containers/busybox + command: [ "/bin/sh", "-c", "env" ] + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + restartPolicy: Never diff --git a/pkg/api/testing/fuzzer.go b/pkg/api/testing/fuzzer.go index a5d9adee6dd..0e53b2c33e7 100644 --- a/pkg/api/testing/fuzzer.go +++ b/pkg/api/testing/fuzzer.go @@ -196,12 +196,12 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { ev.Value = c.RandString() } else { ev.ValueFrom = &api.EnvVarSource{} - ev.ValueFrom.FieldPath = &api.ObjectFieldSelector{} + ev.ValueFrom.FieldRef = &api.ObjectFieldSelector{} versions := []string{"v1beta1", "v1beta2", "v1beta3"} - ev.ValueFrom.FieldPath.APIVersion = versions[c.Rand.Intn(len(versions))] - ev.ValueFrom.FieldPath.FieldPath = c.RandString() + ev.ValueFrom.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))] + ev.ValueFrom.FieldRef.FieldPath = c.RandString() } }, func(e *api.Event, c fuzz.Continue) { diff --git a/pkg/api/types.go b/pkg/api/types.go index 83079260ad9..7328b459d28 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -518,7 +518,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Required: Selects a field of the pod; only name and namespace are supported. - FieldPath *ObjectFieldSelector `json:"fieldPath"` + FieldRef *ObjectFieldSelector `json:"fieldRef"` } // ObjectFieldSelector selects an APIVersioned field of an object. diff --git a/pkg/api/v1/defaults_test.go b/pkg/api/v1/defaults_test.go index ff5ab4d28c6..09667ef841c 100644 --- a/pkg/api/v1/defaults_test.go +++ b/pkg/api/v1/defaults_test.go @@ -330,7 +330,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { Env: []current.EnvVar{ { ValueFrom: ¤t.EnvVarSource{ - FieldPath: ¤t.ObjectFieldSelector{}, + FieldRef: ¤t.ObjectFieldSelector{}, }, }, }, @@ -344,7 +344,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { pod2 := obj2.(*current.Pod) s2 := pod2.Spec - apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion + apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion if apiVersion != "v1" { t.Errorf("Expected default APIVersion v1, got: %v", apiVersion) } diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 52609464fa1..cbde94d06b5 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -529,7 +529,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Required: Selects a field of the pod; only name and namespace are supported. - FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"` + FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` } // ObjectFieldSelector selects an APIVersioned field of an object. diff --git a/pkg/api/v1beta1/defaults_test.go b/pkg/api/v1beta1/defaults_test.go index d826abcd976..988a87d8a05 100644 --- a/pkg/api/v1beta1/defaults_test.go +++ b/pkg/api/v1beta1/defaults_test.go @@ -322,7 +322,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { Env: []current.EnvVar{ { ValueFrom: ¤t.EnvVarSource{ - FieldPath: ¤t.ObjectFieldSelector{}, + FieldRef: ¤t.ObjectFieldSelector{}, }, }, }, @@ -335,7 +335,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { sList2 := obj2.(*current.ContainerManifestList) s2 := sList2.Items[0] - apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion + apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion if apiVersion != "v1beta1" { t.Errorf("Expected default APIVersion v1beta1, got: %v", apiVersion) } diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 92fd9b47966..35e550e0f9c 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -414,7 +414,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Required: Selects a field of the pod; only name and namespace are supported. - FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"` + FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` } // ObjectFieldSelector selects an APIVersioned field of an object. diff --git a/pkg/api/v1beta2/defaults_test.go b/pkg/api/v1beta2/defaults_test.go index f50fb84ec66..10e7ae25323 100644 --- a/pkg/api/v1beta2/defaults_test.go +++ b/pkg/api/v1beta2/defaults_test.go @@ -321,7 +321,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { Env: []current.EnvVar{ { ValueFrom: ¤t.EnvVarSource{ - FieldPath: ¤t.ObjectFieldSelector{}, + FieldRef: ¤t.ObjectFieldSelector{}, }, }, }, @@ -334,7 +334,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { sList2 := obj2.(*current.ContainerManifestList) s2 := sList2.Items[0] - apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion + apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion if apiVersion != "v1beta2" { t.Errorf("Expected default APIVersion v1beta2, got: %v", apiVersion) } diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 35ae1027dfa..50a849bbac8 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -391,7 +391,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Required: Selects a field of the pod; only name and namespace are supported. - FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"` + FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` } // ObjectFieldSelector selects an APIVersioned field of an object. diff --git a/pkg/api/v1beta3/conversion.go b/pkg/api/v1beta3/conversion.go index cac55e0bc30..b78c0b53ced 100644 --- a/pkg/api/v1beta3/conversion.go +++ b/pkg/api/v1beta3/conversion.go @@ -632,14 +632,14 @@ func convert_api_EnvVar_To_v1beta3_EnvVar(in *newer.EnvVar, out *EnvVar, s conve } func convert_v1beta3_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *newer.EnvVarSource, s conversion.Scope) error { - if err := s.Convert(&in.FieldPath, &out.FieldPath, 0); err != nil { + if err := s.Convert(&in.FieldRef, &out.FieldRef, 0); err != nil { return err } return nil } func convert_api_EnvVarSource_To_v1beta3_EnvVarSource(in *newer.EnvVarSource, out *EnvVarSource, s conversion.Scope) error { - if err := s.Convert(&in.FieldPath, &out.FieldPath, 0); err != nil { + if err := s.Convert(&in.FieldRef, &out.FieldRef, 0); err != nil { return err } return nil diff --git a/pkg/api/v1beta3/defaults_test.go b/pkg/api/v1beta3/defaults_test.go index 037628bb03d..4bd9f652e2f 100644 --- a/pkg/api/v1beta3/defaults_test.go +++ b/pkg/api/v1beta3/defaults_test.go @@ -330,7 +330,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { Env: []current.EnvVar{ { ValueFrom: ¤t.EnvVarSource{ - FieldPath: ¤t.ObjectFieldSelector{}, + FieldRef: ¤t.ObjectFieldSelector{}, }, }, }, @@ -344,7 +344,7 @@ func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) { pod2 := obj2.(*current.Pod) s2 := pod2.Spec - apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldPath.APIVersion + apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion if apiVersion != "v1beta3" { t.Errorf("Expected default APIVersion v1beta3, got: %v", apiVersion) } diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index 970654d86c0..e5b9af7c759 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -529,7 +529,7 @@ type EnvVar struct { // EnvVarSource represents a source for the value of an EnvVar. type EnvVarSource struct { // Required: Selects a field of the pod; only name and namespace are supported. - FieldPath *ObjectFieldSelector `json:"fieldPath" description:"selects a field of the pod; only name and namespace are supported"` + FieldRef *ObjectFieldSelector `json:"fieldRef" description:"selects a field of the pod; only name and namespace are supported"` } // ObjectFieldSelector selects an APIVersioned field of an object. diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 93d673af8c6..519ecb05ad7 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -591,9 +591,9 @@ func validateEnvVarValueFrom(ev api.EnvVar) errs.ValidationErrorList { numSources := 0 switch { - case ev.ValueFrom.FieldPath != nil: + case ev.ValueFrom.FieldRef != nil: numSources++ - allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldPath).Prefix("fieldPath")...) + allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef).Prefix("fieldRef")...) } if ev.Value != "" && numSources != 0 { diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 8d65cbceff1..eb3aac8d87a 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -636,7 +636,7 @@ func TestValidateEnv(t *testing.T) { { Name: "abc", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.name", }, @@ -668,7 +668,7 @@ func TestValidateEnv(t *testing.T) { Name: "abc", Value: "foo", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.name", }, @@ -681,50 +681,50 @@ func TestValidateEnv(t *testing.T) { envs: []api.EnvVar{{ Name: "abc", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", }, }, }}, - expectedError: "[0].valueFrom.fieldPath.fieldPath: required value", + expectedError: "[0].valueFrom.fieldRef.fieldPath: required value", }, { name: "missing APIVersion on ObjectFieldSelector", envs: []api.EnvVar{{ Name: "abc", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ FieldPath: "metadata.name", }, }, }}, - expectedError: "[0].valueFrom.fieldPath.apiVersion: required value", + expectedError: "[0].valueFrom.fieldRef.apiVersion: required value", }, { name: "invalid fieldPath", envs: []api.EnvVar{{ Name: "abc", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ FieldPath: "metadata.whoops", APIVersion: "v1beta3", }, }, }}, - expectedError: "[0].valueFrom.fieldPath.fieldPath: invalid value 'metadata.whoops': error converting fieldPath", + expectedError: "[0].valueFrom.fieldRef.fieldPath: invalid value 'metadata.whoops': error converting fieldPath", }, { name: "unsupported fieldPath", envs: []api.EnvVar{{ Name: "abc", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ FieldPath: "status.phase", APIVersion: "v1beta3", }, }, }}, - expectedError: "[0].valueFrom.fieldPath.fieldPath: unsupported value 'status.phase'", + expectedError: "[0].valueFrom.fieldRef.fieldPath: unsupported value 'status.phase'", }, } for _, tc := range errorCases { diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 8daa798d231..bde538b75a3 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -798,8 +798,8 @@ func (kl *Kubelet) runtimeEnvVarValue(envVar api.EnvVar, pod *api.Pod) (string, return runtimeVal, nil } - if envVar.ValueFrom != nil && envVar.ValueFrom.FieldPath != nil { - return kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldPath, pod) + if envVar.ValueFrom != nil && envVar.ValueFrom.FieldRef != nil { + return kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod) } return runtimeVal, nil diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index d6558913633..44b06c4f88a 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -2181,7 +2181,7 @@ func TestMakeEnvironmentVariables(t *testing.T) { { Name: "POD_NAME", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.name", }, @@ -2190,7 +2190,7 @@ func TestMakeEnvironmentVariables(t *testing.T) { { Name: "POD_NAMESPACE", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.namespace", }, diff --git a/test/e2e/downward_api.go b/test/e2e/downward_api.go index 62f9034a479..86098feb1d4 100644 --- a/test/e2e/downward_api.go +++ b/test/e2e/downward_api.go @@ -66,7 +66,7 @@ var _ = Describe("Downward API", func() { { Name: "POD_NAME", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.name", }, @@ -75,7 +75,7 @@ var _ = Describe("Downward API", func() { { Name: "POD_NAMESPACE", ValueFrom: &api.EnvVarSource{ - FieldPath: &api.ObjectFieldSelector{ + FieldRef: &api.ObjectFieldSelector{ APIVersion: "v1beta3", FieldPath: "metadata.namespace", },