Merge pull request #18298 from pmorie/secret-env

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2016-01-20 03:55:40 -08:00
commit 1c861d43ac
21 changed files with 30624 additions and 29609 deletions

View File

@ -14536,13 +14536,10 @@
"v1.SecretVolumeSource": {
"id": "v1.SecretVolumeSource",
"description": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.",
"required": [
"secretName"
],
"properties": {
"secretName": {
"type": "string",
"description": "SecretName is the name of a secret in the pod's namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets"
"description": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets"
}
}
},
@ -14770,6 +14767,10 @@
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."
},
"secretKeyRef": {
"$ref": "v1.SecretKeySelector",
"description": "Selects a key of a secret in the pod's namespace"
}
}
},
@ -14790,6 +14791,23 @@
}
}
},
"v1.SecretKeySelector": {
"id": "v1.SecretKeySelector",
"description": "SecretKeySelector selects a key of a Secret.",
"required": [
"key"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names"
},
"key": {
"type": "string",
"description": "The key of the secret to select from. Must be a valid secret key."
}
}
},
"v1.VolumeMount": {
"id": "v1.VolumeMount",
"description": "VolumeMount describes a mounting of a Volume within a container.",

View File

@ -4360,13 +4360,10 @@
"v1.SecretVolumeSource": {
"id": "v1.SecretVolumeSource",
"description": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.",
"required": [
"secretName"
],
"properties": {
"secretName": {
"type": "string",
"description": "SecretName is the name of a secret in the pod's namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets"
"description": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets"
}
}
},
@ -4860,6 +4857,10 @@
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."
},
"secretKeyRef": {
"$ref": "v1.SecretKeySelector",
"description": "Selects a key of a secret in the pod's namespace"
}
}
},
@ -4880,6 +4881,23 @@
}
}
},
"v1.SecretKeySelector": {
"id": "v1.SecretKeySelector",
"description": "SecretKeySelector selects a key of a Secret.",
"required": [
"key"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names"
},
"key": {
"type": "string",
"description": "The key of the secret to select from. Must be a valid secret key."
}
}
},
"v1.ResourceRequirements": {
"id": "v1.ResourceRequirements",
"description": "ResourceRequirements describes the compute resource requirements.",

View File

@ -3002,8 +3002,8 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">SecretName is the name of a secret in the pod&#8217;s namespace. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets">http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the secret in the pod&#8217;s namespace to use. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets">http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
@ -3089,6 +3089,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_configmapkeyselector">v1.ConfigMapKeySelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretKeyRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a key of a secret in the pod&#8217;s namespace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_secretkeyselector">v1.SecretKeySelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -3655,6 +3662,47 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_secretkeyselector">v1.SecretKeySelector</h3>
<div class="paragraph">
<p>SecretKeySelector selects a key of a Secret.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the referent. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names">http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">key</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The key of the secret to select from. Must be a valid secret key.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_capability">v1.Capability</h3>
@ -4525,7 +4573,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-01-14 15:18:11 UTC
Last updated 2016-01-18 17:24:36 UTC
</div>
</div>
</body>

View File

@ -2517,8 +2517,8 @@ The resulting set of endpoints can be viewed as:<br>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">SecretName is the name of a secret in the pod&#8217;s namespace. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets">http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the secret in the pod&#8217;s namespace to use. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets">http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
@ -2625,6 +2625,13 @@ The resulting set of endpoints can be viewed as:<br>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_configmapkeyselector">v1.ConfigMapKeySelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">secretKeyRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a key of a secret in the pod&#8217;s namespace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_secretkeyselector">v1.SecretKeySelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -3195,6 +3202,47 @@ The resulting set of endpoints can be viewed as:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_secretkeyselector">v1.SecretKeySelector</h3>
<div class="paragraph">
<p>SecretKeySelector selects a key of a Secret.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the referent. More info: <a href="http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names">http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">key</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The key of the secret to select from. Must be a valid secret key.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_replicationcontroller">v1.ReplicationController</h3>
@ -5516,6 +5564,54 @@ The resulting set of endpoints can be viewed as:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_containerstate">v1.ContainerState</h3>
<div class="paragraph">
<p>ContainerState holds a possible state of container. Only one of its members may be specified. If none of them is specified, the default one is ContainerStateWaiting.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">waiting</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a waiting container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstatewaiting">v1.ContainerStateWaiting</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">running</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a running container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstaterunning">v1.ContainerStateRunning</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">terminated</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a terminated container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstateterminated">v1.ContainerStateTerminated</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_securitycontext">v1.SecurityContext</h3>
@ -5578,54 +5674,6 @@ The resulting set of endpoints can be viewed as:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_containerstate">v1.ContainerState</h3>
<div class="paragraph">
<p>ContainerState holds a possible state of container. Only one of its members may be specified. If none of them is specified, the default one is ContainerStateWaiting.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">waiting</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a waiting container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstatewaiting">v1.ContainerStateWaiting</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">running</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a running container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstaterunning">v1.ContainerStateRunning</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">terminated</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Details about a terminated container</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_containerstateterminated">v1.ContainerStateTerminated</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_awselasticblockstorevolumesource">v1.AWSElasticBlockStoreVolumeSource</h3>
@ -7097,7 +7145,7 @@ The resulting set of endpoints can be viewed as:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-01-14 15:17:59 UTC
Last updated 2016-01-18 17:24:26 UTC
</div>
</div>
</body>

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_SECRET_DATA
valueFrom:
secretKeyRef:
name: test-secret
key: data-1
restartPolicy: Never

View File

@ -354,8 +354,9 @@ func TestExampleObjectSchemas(t *testing.T) {
"rc": &api.ReplicationController{},
},
"../docs/user-guide/secrets": {
"secret-pod": &api.Pod{},
"secret": &api.Secret{},
"secret-pod": &api.Pod{},
"secret": &api.Secret{},
"secret-env-pod": &api.Pod{},
},
"../examples/spark": {
"spark-master-controller": &api.ReplicationController{},

View File

@ -141,6 +141,7 @@ func init() {
deepCopy_api_ResourceRequirements,
deepCopy_api_SELinuxOptions,
deepCopy_api_Secret,
deepCopy_api_SecretKeySelector,
deepCopy_api_SecretList,
deepCopy_api_SecretVolumeSource,
deepCopy_api_SecurityContext,
@ -700,6 +701,15 @@ func deepCopy_api_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion
} else {
out.ConfigMapKeyRef = nil
}
if in.SecretKeyRef != nil {
in, out := in.SecretKeyRef, &out.SecretKeyRef
*out = new(SecretKeySelector)
if err := deepCopy_api_SecretKeySelector(*in, *out, c); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -2333,6 +2343,14 @@ func deepCopy_api_Secret(in Secret, out *Secret, c *conversion.Cloner) error {
return nil
}
func deepCopy_api_SecretKeySelector(in SecretKeySelector, out *SecretKeySelector, c *conversion.Cloner) error {
if err := deepCopy_api_LocalObjectReference(in.LocalObjectReference, &out.LocalObjectReference, c); err != nil {
return err
}
out.Key = in.Key
return nil
}
func deepCopy_api_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err

File diff suppressed because it is too large Load Diff

View File

@ -560,8 +560,8 @@ type GitRepoVolumeSource struct {
// as files using the keys in the Data field as the file names.
// Secret volumes support ownership management and SELinux relabeling.
type SecretVolumeSource struct {
// Name of the secret in the pod's namespace to use
SecretName string `json:"secretName"`
// Name of the secret in the pod's namespace to use.
SecretName string `json:"secretName,omitempty"`
}
// Represents an NFS mount that lasts the lifetime of a pod.
@ -721,6 +721,8 @@ type EnvVarSource struct {
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Selects a key of a secret in the pod's namespace.
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
}
// ObjectFieldSelector selects an APIVersioned field of an object.
@ -741,6 +743,14 @@ type ConfigMapKeySelector struct {
Key string `json:"key"`
}
// SecretKeySelector selects a key of a Secret.
type SecretKeySelector struct {
// The name of the secret in the pod's namespace to select from.
LocalObjectReference `json:",inline"`
// The key of the secret to select from. Must be a valid secret key.
Key string `json:"key"`
}
// HTTPGetAction describes an action based on HTTP Get requests.
type HTTPGetAction struct {
// Optional: Path to access on the HTTP server.

View File

@ -722,6 +722,15 @@ func autoConvert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *
} else {
out.ConfigMapKeyRef = nil
}
// unable to generate simple pointer conversion for api.SecretKeySelector -> v1.SecretKeySelector
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(SecretKeySelector)
if err := Convert_api_SecretKeySelector_To_v1_SecretKeySelector(in.SecretKeyRef, out.SecretKeyRef, s); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -2731,6 +2740,21 @@ func Convert_api_Secret_To_v1_Secret(in *api.Secret, out *Secret, s conversion.S
return autoConvert_api_Secret_To_v1_Secret(in, out, s)
}
func autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector(in *api.SecretKeySelector, out *SecretKeySelector, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*api.SecretKeySelector))(in)
}
if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
return err
}
out.Key = in.Key
return nil
}
func Convert_api_SecretKeySelector_To_v1_SecretKeySelector(in *api.SecretKeySelector, out *SecretKeySelector, s conversion.Scope) error {
return autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector(in, out, s)
}
func autoConvert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*api.SecretList))(in)
@ -3935,6 +3959,15 @@ func autoConvert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.
} else {
out.ConfigMapKeyRef = nil
}
// unable to generate simple pointer conversion for v1.SecretKeySelector -> api.SecretKeySelector
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(api.SecretKeySelector)
if err := Convert_v1_SecretKeySelector_To_api_SecretKeySelector(in.SecretKeyRef, out.SecretKeyRef, s); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -5836,6 +5869,21 @@ func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.S
return autoConvert_v1_Secret_To_api_Secret(in, out, s)
}
func autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector(in *SecretKeySelector, out *api.SecretKeySelector, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*SecretKeySelector))(in)
}
if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
return err
}
out.Key = in.Key
return nil
}
func Convert_v1_SecretKeySelector_To_api_SecretKeySelector(in *SecretKeySelector, out *api.SecretKeySelector, s conversion.Scope) error {
return autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector(in, out, s)
}
func autoConvert_v1_SecretList_To_api_SecretList(in *SecretList, out *api.SecretList, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*SecretList))(in)
@ -6437,6 +6485,7 @@ func init() {
autoConvert_api_ResourceQuota_To_v1_ResourceQuota,
autoConvert_api_ResourceRequirements_To_v1_ResourceRequirements,
autoConvert_api_SELinuxOptions_To_v1_SELinuxOptions,
autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector,
autoConvert_api_SecretList_To_v1_SecretList,
autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource,
autoConvert_api_Secret_To_v1_Secret,
@ -6560,6 +6609,7 @@ func init() {
autoConvert_v1_ResourceQuota_To_api_ResourceQuota,
autoConvert_v1_ResourceRequirements_To_api_ResourceRequirements,
autoConvert_v1_SELinuxOptions_To_api_SELinuxOptions,
autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector,
autoConvert_v1_SecretList_To_api_SecretList,
autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource,
autoConvert_v1_Secret_To_api_Secret,

View File

@ -549,6 +549,14 @@ func deepCopy_v1_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion.
} else {
out.ConfigMapKeyRef = nil
}
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(SecretKeySelector)
if err := deepCopy_v1_SecretKeySelector(*in.SecretKeyRef, out.SecretKeyRef, c); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -2065,6 +2073,14 @@ func deepCopy_v1_Secret(in Secret, out *Secret, c *conversion.Cloner) error {
return nil
}
func deepCopy_v1_SecretKeySelector(in SecretKeySelector, out *SecretKeySelector, c *conversion.Cloner) error {
if err := deepCopy_v1_LocalObjectReference(in.LocalObjectReference, &out.LocalObjectReference, c); err != nil {
return err
}
out.Key = in.Key
return nil
}
func deepCopy_v1_SecretList(in SecretList, out *SecretList, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
@ -2579,6 +2595,7 @@ func init() {
deepCopy_v1_ResourceRequirements,
deepCopy_v1_SELinuxOptions,
deepCopy_v1_Secret,
deepCopy_v1_SecretKeySelector,
deepCopy_v1_SecretList,
deepCopy_v1_SecretVolumeSource,
deepCopy_v1_SecurityContext,

File diff suppressed because it is too large Load Diff

View File

@ -724,9 +724,9 @@ type GitRepoVolumeSource struct {
// as files using the keys in the Data field as the file names.
// Secret volumes support ownership management and SELinux relabeling.
type SecretVolumeSource struct {
// SecretName is the name of a secret in the pod's namespace.
// Name of the secret in the pod's namespace to use.
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets
SecretName string `json:"secretName"`
SecretName string `json:"secretName,omitempty"`
}
// Represents an NFS mount that lasts the lifetime of a pod.
@ -847,6 +847,8 @@ type EnvVarSource struct {
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Selects a key of a secret in the pod's namespace
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`
}
// ObjectFieldSelector selects an APIVersioned field of an object.
@ -865,6 +867,14 @@ type ConfigMapKeySelector struct {
Key string `json:"key"`
}
// SecretKeySelector selects a key of a Secret.
type SecretKeySelector struct {
// The name of the secret in the pod's namespace to select from.
LocalObjectReference `json:",inline"`
// The key of the secret to select from. Must be a valid secret key.
Key string `json:"key"`
}
// HTTPGetAction describes an action based on HTTP Get requests.
type HTTPGetAction struct {
// Path to access on the HTTP server.

View File

@ -347,6 +347,7 @@ var map_EnvVarSource = map[string]string{
"": "EnvVarSource represents a source for the value of an EnvVar.",
"fieldRef": "Selects a field of the pod; only name and namespace are supported.",
"configMapKeyRef": "Selects a key of a ConfigMap.",
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
}
func (EnvVarSource) SwaggerDoc() map[string]string {
@ -1271,6 +1272,15 @@ func (Secret) SwaggerDoc() map[string]string {
return map_Secret
}
var map_SecretKeySelector = map[string]string{
"": "SecretKeySelector selects a key of a Secret.",
"key": "The key of the secret to select from. Must be a valid secret key.",
}
func (SecretKeySelector) SwaggerDoc() map[string]string {
return map_SecretKeySelector
}
var map_SecretList = map[string]string{
"": "SecretList is a list of Secret.",
"metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
@ -1283,7 +1293,7 @@ func (SecretList) SwaggerDoc() map[string]string {
var map_SecretVolumeSource = map[string]string{
"": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.",
"secretName": "SecretName is the name of a secret in the pod's namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets",
"secretName": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets",
}
func (SecretVolumeSource) SwaggerDoc() map[string]string {

View File

@ -964,17 +964,25 @@ func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList
numSources := 0
switch {
case ev.ValueFrom.FieldRef != nil:
if ev.ValueFrom.FieldRef != nil {
numSources++
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef, &validFieldPathExpressionsEnv, fldPath.Child("fieldRef"))...)
case ev.ValueFrom.ConfigMapKeyRef != nil:
}
if ev.ValueFrom.ConfigMapKeyRef != nil {
numSources++
allErrs = append(allErrs, validateConfigMapKeySelector(ev.ValueFrom.ConfigMapKeyRef, fldPath.Child("configMapKeyRef"))...)
}
if ev.ValueFrom.SecretKeyRef != nil {
numSources++
allErrs = append(allErrs, validateSecretKeySelector(ev.ValueFrom.SecretKeyRef, fldPath.Child("secretKeyRef"))...)
}
if len(ev.Value) != 0 && numSources != 0 {
allErrs = append(allErrs, field.Invalid(fldPath, "", "may not be specified when `value` is not empty"))
if len(ev.Value) != 0 {
if numSources != 0 {
allErrs = append(allErrs, field.Invalid(fldPath, "", "may not be specified when `value` is not empty"))
}
} else if numSources != 1 {
allErrs = append(allErrs, field.Invalid(fldPath, "", "may not have more than one field specified at a time"))
}
return allErrs
@ -1014,6 +1022,21 @@ func validateConfigMapKeySelector(s *api.ConfigMapKeySelector, fldPath *field.Pa
return allErrs
}
func validateSecretKeySelector(s *api.SecretKeySelector, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(s.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
}
if len(s.Key) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("key"), ""))
} else if !IsSecretKey(s.Key) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("key"), s.Key, fmt.Sprintf("must have at most %d characters and match regex %s", validation.DNS1123SubdomainMaxLength, SecretKeyFmt)))
}
return allErrs
}
func validateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

View File

@ -812,6 +812,17 @@ func TestValidateEnv(t *testing.T) {
},
},
},
{
Name: "secret_value",
ValueFrom: &api.EnvVarSource{
SecretKeyRef: &api.SecretKeySelector{
LocalObjectReference: api.LocalObjectReference{
Name: "some-secret",
},
Key: "secret-key",
},
},
},
}
if errs := validateEnv(successCase, field.NewPath("field")); len(errs) != 0 {
t.Errorf("expected success: %v", errs)
@ -846,6 +857,25 @@ func TestValidateEnv(t *testing.T) {
}},
expectedError: "[0].valueFrom: Invalid value: \"\": may not be specified when `value` is not empty",
},
{
name: "FieldRef and SecretKeyRef specified",
envs: []api.EnvVar{{
Name: "abc",
ValueFrom: &api.EnvVarSource{
FieldRef: &api.ObjectFieldSelector{
APIVersion: testapi.Default.GroupVersion().String(),
FieldPath: "metadata.name",
},
SecretKeyRef: &api.SecretKeySelector{
LocalObjectReference: api.LocalObjectReference{
Name: "a-secret",
},
Key: "a-key",
},
},
}},
expectedError: "[0].valueFrom: Invalid value: \"\": may not have more than one field specified at a time",
},
{
name: "missing FieldPath on ObjectFieldSelector",
envs: []api.EnvVar{{

View File

@ -255,6 +255,14 @@ func deepCopy_api_EnvVarSource(in api.EnvVarSource, out *api.EnvVarSource, c *co
} else {
out.ConfigMapKeyRef = nil
}
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(api.SecretKeySelector)
if err := deepCopy_api_SecretKeySelector(*in.SecretKeyRef, out.SecretKeyRef, c); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -692,6 +700,14 @@ func deepCopy_api_SELinuxOptions(in api.SELinuxOptions, out *api.SELinuxOptions,
return nil
}
func deepCopy_api_SecretKeySelector(in api.SecretKeySelector, out *api.SecretKeySelector, c *conversion.Cloner) error {
if err := deepCopy_api_LocalObjectReference(in.LocalObjectReference, &out.LocalObjectReference, c); err != nil {
return err
}
out.Key = in.Key
return nil
}
func deepCopy_api_SecretVolumeSource(in api.SecretVolumeSource, out *api.SecretVolumeSource, c *conversion.Cloner) error {
out.SecretName = in.SecretName
return nil
@ -1711,6 +1727,7 @@ func init() {
deepCopy_api_RBDVolumeSource,
deepCopy_api_ResourceRequirements,
deepCopy_api_SELinuxOptions,
deepCopy_api_SecretKeySelector,
deepCopy_api_SecretVolumeSource,
deepCopy_api_SecurityContext,
deepCopy_api_TCPSocketAction,

View File

@ -343,6 +343,15 @@ func autoConvert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *
} else {
out.ConfigMapKeyRef = nil
}
// unable to generate simple pointer conversion for api.SecretKeySelector -> v1.SecretKeySelector
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(v1.SecretKeySelector)
if err := Convert_api_SecretKeySelector_To_v1_SecretKeySelector(in.SecretKeyRef, out.SecretKeyRef, s); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -950,6 +959,21 @@ func Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in *api.SELinuxOptions, out
return autoConvert_api_SELinuxOptions_To_v1_SELinuxOptions(in, out, s)
}
func autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector(in *api.SecretKeySelector, out *v1.SecretKeySelector, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*api.SecretKeySelector))(in)
}
if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
return err
}
out.Key = in.Key
return nil
}
func Convert_api_SecretKeySelector_To_v1_SecretKeySelector(in *api.SecretKeySelector, out *v1.SecretKeySelector, s conversion.Scope) error {
return autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector(in, out, s)
}
func autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *v1.SecretVolumeSource, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*api.SecretVolumeSource))(in)
@ -1530,6 +1554,15 @@ func autoConvert_v1_EnvVarSource_To_api_EnvVarSource(in *v1.EnvVarSource, out *a
} else {
out.ConfigMapKeyRef = nil
}
// unable to generate simple pointer conversion for v1.SecretKeySelector -> api.SecretKeySelector
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(api.SecretKeySelector)
if err := Convert_v1_SecretKeySelector_To_api_SecretKeySelector(in.SecretKeyRef, out.SecretKeyRef, s); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -2113,6 +2146,21 @@ func Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in *v1.SELinuxOptions, out
return autoConvert_v1_SELinuxOptions_To_api_SELinuxOptions(in, out, s)
}
func autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector(in *v1.SecretKeySelector, out *api.SecretKeySelector, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*v1.SecretKeySelector))(in)
}
if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
return err
}
out.Key = in.Key
return nil
}
func Convert_v1_SecretKeySelector_To_api_SecretKeySelector(in *v1.SecretKeySelector, out *api.SecretKeySelector, s conversion.Scope) error {
return autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector(in, out, s)
}
func autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *v1.SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error {
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
defaulting.(func(*v1.SecretVolumeSource))(in)
@ -4538,6 +4586,7 @@ func init() {
autoConvert_api_RBDVolumeSource_To_v1_RBDVolumeSource,
autoConvert_api_ResourceRequirements_To_v1_ResourceRequirements,
autoConvert_api_SELinuxOptions_To_v1_SELinuxOptions,
autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector,
autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource,
autoConvert_api_SecurityContext_To_v1_SecurityContext,
autoConvert_api_TCPSocketAction_To_v1_TCPSocketAction,
@ -4628,6 +4677,7 @@ func init() {
autoConvert_v1_RBDVolumeSource_To_api_RBDVolumeSource,
autoConvert_v1_ResourceRequirements_To_api_ResourceRequirements,
autoConvert_v1_SELinuxOptions_To_api_SELinuxOptions,
autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector,
autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource,
autoConvert_v1_SecurityContext_To_api_SecurityContext,
autoConvert_v1_TCPSocketAction_To_api_TCPSocketAction,

View File

@ -291,6 +291,14 @@ func deepCopy_v1_EnvVarSource(in v1.EnvVarSource, out *v1.EnvVarSource, c *conve
} else {
out.ConfigMapKeyRef = nil
}
if in.SecretKeyRef != nil {
out.SecretKeyRef = new(v1.SecretKeySelector)
if err := deepCopy_v1_SecretKeySelector(*in.SecretKeyRef, out.SecretKeyRef, c); err != nil {
return err
}
} else {
out.SecretKeyRef = nil
}
return nil
}
@ -729,6 +737,14 @@ func deepCopy_v1_SELinuxOptions(in v1.SELinuxOptions, out *v1.SELinuxOptions, c
return nil
}
func deepCopy_v1_SecretKeySelector(in v1.SecretKeySelector, out *v1.SecretKeySelector, c *conversion.Cloner) error {
if err := deepCopy_v1_LocalObjectReference(in.LocalObjectReference, &out.LocalObjectReference, c); err != nil {
return err
}
out.Key = in.Key
return nil
}
func deepCopy_v1_SecretVolumeSource(in v1.SecretVolumeSource, out *v1.SecretVolumeSource, c *conversion.Cloner) error {
out.SecretName = in.SecretName
return nil
@ -1754,6 +1770,7 @@ func init() {
deepCopy_v1_RBDVolumeSource,
deepCopy_v1_ResourceRequirements,
deepCopy_v1_SELinuxOptions,
deepCopy_v1_SecretKeySelector,
deepCopy_v1_SecretVolumeSource,
deepCopy_v1_SecurityContext,
deepCopy_v1_TCPSocketAction,

View File

@ -1369,6 +1369,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Contain
var (
tmpEnv = make(map[string]string)
configMaps = make(map[string]*apiextensions.ConfigMap)
secrets = make(map[string]*api.Secret)
mappingFunc = expansion.MappingFuncFor(tmpEnv, serviceEnv)
)
for _, envVar := range container.Env {
@ -1405,6 +1406,21 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Contain
if !ok {
return result, fmt.Errorf("Couldn't find key %v in ConfigMap %v/%v", key, pod.Namespace, name)
}
case envVar.ValueFrom.SecretKeyRef != nil:
name := envVar.ValueFrom.SecretKeyRef.Name
key := envVar.ValueFrom.SecretKeyRef.Key
secret, ok := secrets[name]
if !ok {
secret, err = kl.kubeClient.Secrets(pod.Namespace).Get(name)
if err != nil {
return result, err
}
}
runtimeValBytes, ok := secret.Data[key]
if !ok {
return result, fmt.Errorf("Couldn't find key %v in Secret %v/%v", key, pod.Namespace, name)
}
runtimeVal = string(runtimeValBytes)
}
}

View File

@ -28,7 +28,7 @@ import (
var _ = Describe("Secrets", func() {
f := NewFramework("secrets")
It("should be consumable from pods [Conformance]", func() {
It("should be consumable from pods in volume [Conformance]", func() {
name := "secret-test-" + string(util.NewUUID())
volumeName := "secret-volume"
volumeMountPath := "/etc/secret-volume"
@ -74,7 +74,7 @@ var _ = Describe("Secrets", func() {
},
Containers: []api.Container{
{
Name: "secret-test",
Name: "secret-volume-test",
Image: "gcr.io/google_containers/mounttest:0.2",
Args: []string{
"--file_content=/etc/secret-volume/data-1",
@ -97,4 +97,63 @@ var _ = Describe("Secrets", func() {
"mode of file \"/etc/secret-volume/data-1\": -r--r--r--",
}, f.Namespace.Name)
})
It("should be consumable from pods in env vars [Conformance]", func() {
name := "secret-test-" + string(util.NewUUID())
secret := &api.Secret{
ObjectMeta: api.ObjectMeta{
Namespace: f.Namespace.Name,
Name: name,
},
Data: map[string][]byte{
"data-1": []byte("value-1"),
},
}
By(fmt.Sprintf("Creating secret with name %s", secret.Name))
defer func() {
By("Cleaning up the secret")
if err := f.Client.Secrets(f.Namespace.Name).Delete(secret.Name); err != nil {
Failf("unable to delete secret %v: %v", secret.Name, err)
}
}()
var err error
if secret, err = f.Client.Secrets(f.Namespace.Name).Create(secret); err != nil {
Failf("unable to create test secret %s: %v", secret.Name, err)
}
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "pod-secrets-" + string(util.NewUUID()),
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "secret-env-test",
Image: "gcr.io/google_containers/busybox",
Command: []string{"sh", "-c", "env"},
Env: []api.EnvVar{
{
Name: "SECRET_DATA",
ValueFrom: &api.EnvVarSource{
SecretKeyRef: &api.SecretKeySelector{
LocalObjectReference: api.LocalObjectReference{
Name: name,
},
Key: "data-1",
},
},
},
},
},
},
RestartPolicy: api.RestartPolicyNever,
},
}
testContainerOutput("consume secrets", f.Client, pod, 0, []string{
"SECRET_DATA=value-1",
}, f.Namespace.Name)
})
})