Merge pull request #39981 from fraenkel/optional_configmaps_secrets
Automatic merge from submit-queue
Optional configmaps and secrets
Allow configmaps and secrets for environment variables and volume sources to be optional
Implements approved proposal c9f881b7bb
Release note:
```release-note
Volumes and environment variables populated from ConfigMap and Secret objects can now tolerate the named source object or specific keys being missing, by adding `optional: true` to the volume or environment variable source specifications.
```
This commit is contained in:
commit
43286a82c6
@ -34912,6 +34912,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -34928,6 +34932,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -34967,7 +34975,7 @@
|
||||
"format": "int32"
|
||||
},
|
||||
"items": {
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.KeyToPath"
|
||||
@ -34976,6 +34984,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -38217,6 +38229,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -38233,6 +38249,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret or it's key must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -38272,12 +38292,16 @@
|
||||
"format": "int32"
|
||||
},
|
||||
"items": {
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.KeyToPath"
|
||||
}
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret or it's keys must be defined",
|
||||
"type": "boolean"
|
||||
},
|
||||
"secretName": {
|
||||
"description": "Name of the secret in the pod's namespace to use. More info: http://kubernetes.io/docs/user-guide/volumes#secrets",
|
||||
"type": "string"
|
||||
|
@ -1574,12 +1574,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2005,12 +2009,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2275,6 +2283,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2285,6 +2297,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2345,6 +2361,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key to select."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2362,6 +2382,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key of the secret to select from. Must be a valid secret key."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1579,12 +1579,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2010,12 +2014,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2280,6 +2288,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2290,6 +2302,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2350,6 +2366,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key to select."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2367,6 +2387,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key of the secret to select from. Must be a valid secret key."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -7951,12 +7951,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8382,12 +8386,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8652,6 +8660,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8662,6 +8674,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8722,6 +8738,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key to select."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8739,6 +8759,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key of the secret to select from. Must be a valid secret key."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18428,12 +18428,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18572,12 +18576,16 @@
|
||||
"items": {
|
||||
"$ref": "v1.KeyToPath"
|
||||
},
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'."
|
||||
},
|
||||
"defaultMode": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18744,6 +18752,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18754,6 +18766,10 @@
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names"
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18814,6 +18830,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key to select."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18831,6 +18851,10 @@
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "The key of the secret to select from. Must be a valid secret key."
|
||||
},
|
||||
"optional": {
|
||||
"type": "boolean",
|
||||
"description": "Specify whether the Secret or it's key must be defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1387,7 +1387,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -1399,6 +1399,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -1546,6 +1553,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -3194,7 +3208,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -3206,6 +3220,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">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4055,6 +4076,13 @@ The StatefulSet guarantees that a given network identity will always map to the
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4268,6 +4296,13 @@ The StatefulSet guarantees that a given network identity will always map to the
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4713,6 +4748,13 @@ The StatefulSet guarantees that a given network identity will always map to the
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -5018,7 +5060,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-01-20 19:58:01 UTC
|
||||
Last updated 2017-01-24 01:22:19 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1291,7 +1291,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -1303,6 +1303,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -1450,6 +1457,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -3181,7 +3195,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -3193,6 +3207,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">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4042,6 +4063,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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4255,6 +4283,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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4700,6 +4735,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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4950,7 +4992,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-01-20 19:58:30 UTC
|
||||
Last updated 2017-01-24 01:22:40 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1600,7 +1600,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -1612,6 +1612,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -1697,6 +1704,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -2828,7 +2842,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -2840,6 +2854,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">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -3839,6 +3860,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">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -7171,6 +7199,13 @@ Both these may change in the future. Incoming requests are matched against the h
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -7390,6 +7425,13 @@ Both these may change in the future. Incoming requests are matched against the h
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -7567,7 +7609,7 @@ Both these may change in the future. Incoming requests are matched against the h
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-01-20 19:59:01 UTC
|
||||
Last updated 2017-01-24 01:22:55 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1524,7 +1524,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -1536,6 +1536,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -1738,6 +1745,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -3296,7 +3310,7 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">items</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the <em>..</em> path or start with <em>..</em>.</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_keytopath">v1.KeyToPath</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@ -3308,6 +3322,13 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s keys must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -4387,6 +4408,13 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the Secret or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -8535,6 +8563,13 @@ Examples:<br>
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -8775,6 +8810,13 @@ Examples:<br>
|
||||
<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">optional</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify whether the ConfigMap or it’s key must be defined</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">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -9194,7 +9236,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-01-20 19:57:54 UTC
|
||||
Last updated 2017-01-24 01:22:13 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -10746,6 +10746,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -10762,6 +10766,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap or it's key must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -10801,7 +10809,7 @@
|
||||
"format": "int32"
|
||||
},
|
||||
"items": {
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.KeyToPath"
|
||||
@ -10810,6 +10818,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the ConfigMap or it's keys must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12677,6 +12689,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12693,6 +12709,10 @@
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret or it's key must be defined",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12732,12 +12752,16 @@
|
||||
"format": "int32"
|
||||
},
|
||||
"items": {
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1.KeyToPath"
|
||||
}
|
||||
},
|
||||
"optional": {
|
||||
"description": "Specify whether the Secret or it's keys must be defined",
|
||||
"type": "boolean"
|
||||
},
|
||||
"secretName": {
|
||||
"description": "Name of the secret in the pod's namespace to use. More info: http://kubernetes.io/docs/user-guide/volumes#secrets",
|
||||
"type": "string"
|
||||
|
@ -123,11 +123,17 @@ pkg/util/oom/oom_linux.go: oomScoreAdjPath := path.Join("/proc", pidStr, "oom_sc
|
||||
pkg/util/oom/oom_linux.go:// Writes 'value' to /proc/<pid>/oom_score_adj for all processes in cgroup cgroupName.
|
||||
pkg/util/oom/oom_linux.go:// Writes 'value' to /proc/<pid>/oom_score_adj. PID = 0 means self
|
||||
test/e2e/common/configmap.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volume/data-1"},
|
||||
test/e2e/common/configmap.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/create/data-1"},
|
||||
test/e2e/common/configmap.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/delete/data-1"},
|
||||
test/e2e/common/configmap.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/update/data-3"},
|
||||
test/e2e/common/downwardapi_volume.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=" + filePath},
|
||||
test/e2e/common/host_path.go: fmt.Sprintf("--file_content_in_loop=%v", filePath),
|
||||
test/e2e/common/host_path.go: fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
|
||||
test/e2e/common/host_path.go: fmt.Sprintf("--retry_time=%d", retryDuration),
|
||||
test/e2e/common/host_path.go: fmt.Sprintf("--retry_time=%d", retryDuration),
|
||||
test/e2e/common/secrets.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/create/data-1"},
|
||||
test/e2e/common/secrets.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/delete/data-1"},
|
||||
test/e2e/common/secrets.go: Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/update/data-3"},
|
||||
test/e2e_node/container_manager_test.go: return fmt.Errorf("expected pid %d's oom_score_adj to be %d; found %d", pid, expectedOOMScoreAdj, oomScore)
|
||||
test/e2e_node/container_manager_test.go: return fmt.Errorf("expected pid %d's oom_score_adj to be < %d; found %d", pid, expectedMaxOOMScoreAdj, oomScore)
|
||||
test/e2e_node/container_manager_test.go: return fmt.Errorf("expected pid %d's oom_score_adj to be >= %d; found %d", pid, expectedMinOOMScoreAdj, oomScore)
|
||||
|
@ -286,6 +286,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
|
||||
func(s *api.SecretVolumeSource, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(s) // fuzz self without calling this function again
|
||||
|
||||
if c.RandBool() {
|
||||
opt := c.RandBool()
|
||||
s.Optional = &opt
|
||||
}
|
||||
// DefaultMode should always be set, it has a default
|
||||
// value and it is expected to be between 0 and 0777
|
||||
var mode int32
|
||||
@ -296,6 +300,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
|
||||
func(cm *api.ConfigMapVolumeSource, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(cm) // fuzz self without calling this function again
|
||||
|
||||
if c.RandBool() {
|
||||
opt := c.RandBool()
|
||||
cm.Optional = &opt
|
||||
}
|
||||
// DefaultMode should always be set, it has a default
|
||||
// value and it is expected to be between 0 and 0777
|
||||
var mode int32
|
||||
@ -401,6 +409,10 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
|
||||
},
|
||||
func(cm *api.ConfigMapEnvSource, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(cm) // fuzz self without calling this function again
|
||||
if c.RandBool() {
|
||||
opt := c.RandBool()
|
||||
cm.Optional = &opt
|
||||
}
|
||||
},
|
||||
func(s *api.SecretEnvSource, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(s) // fuzz self without calling this function again
|
||||
|
@ -729,8 +729,8 @@ type SecretVolumeSource struct {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the Secret,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
Items []KeyToPath
|
||||
// Mode bits to use on created files by default. Must be a value between
|
||||
@ -740,6 +740,9 @@ type SecretVolumeSource struct {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
DefaultMode *int32
|
||||
// Specify whether the Secret or it's key must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// Represents an NFS mount that lasts the lifetime of a pod.
|
||||
@ -992,8 +995,8 @@ type ConfigMapVolumeSource struct {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the ConfigMap,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
Items []KeyToPath
|
||||
// Mode bits to use on created files by default. Must be a value between
|
||||
@ -1003,6 +1006,9 @@ type ConfigMapVolumeSource struct {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
DefaultMode *int32
|
||||
// Specify whether the ConfigMap or it's keys must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// Maps a string key to a path within a volume.
|
||||
@ -1124,6 +1130,9 @@ type ConfigMapKeySelector struct {
|
||||
LocalObjectReference
|
||||
// The key to select.
|
||||
Key string
|
||||
// Specify whether the ConfigMap or it's key must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// SecretKeySelector selects a key of a Secret.
|
||||
@ -1132,6 +1141,9 @@ type SecretKeySelector struct {
|
||||
LocalObjectReference
|
||||
// The key of the secret to select from. Must be a valid secret key.
|
||||
Key string
|
||||
// Specify whether the Secret or it's key must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// EnvFromSource represents the source of a set of ConfigMaps
|
||||
@ -1155,6 +1167,9 @@ type EnvFromSource struct {
|
||||
type ConfigMapEnvSource struct {
|
||||
// The ConfigMap to select from.
|
||||
LocalObjectReference
|
||||
// Specify whether the ConfigMap must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// SecretEnvSource selects a Secret to populate the environment
|
||||
@ -1165,6 +1180,9 @@ type ConfigMapEnvSource struct {
|
||||
type SecretEnvSource struct {
|
||||
// The Secret to select from.
|
||||
LocalObjectReference
|
||||
// Specify whether the Secret must be defined
|
||||
// +optional
|
||||
Optional *bool
|
||||
}
|
||||
|
||||
// HTTPHeader describes a custom header to be used in HTTP probes
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -279,6 +279,10 @@ message ConfigMap {
|
||||
message ConfigMapEnvSource {
|
||||
// The ConfigMap to select from.
|
||||
optional LocalObjectReference localObjectReference = 1;
|
||||
|
||||
// Specify whether the ConfigMap must be defined
|
||||
// +optional
|
||||
optional bool optional = 2;
|
||||
}
|
||||
|
||||
// Selects a key from a ConfigMap.
|
||||
@ -288,6 +292,10 @@ message ConfigMapKeySelector {
|
||||
|
||||
// The key to select.
|
||||
optional string key = 2;
|
||||
|
||||
// Specify whether the ConfigMap or it's key must be defined
|
||||
// +optional
|
||||
optional bool optional = 3;
|
||||
}
|
||||
|
||||
// ConfigMapList is a resource containing a list of ConfigMap objects.
|
||||
@ -314,8 +322,8 @@ message ConfigMapVolumeSource {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the ConfigMap,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
repeated KeyToPath items = 2;
|
||||
|
||||
@ -326,6 +334,10 @@ message ConfigMapVolumeSource {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
optional int32 defaultMode = 3;
|
||||
|
||||
// Specify whether the ConfigMap or it's keys must be defined
|
||||
// +optional
|
||||
optional bool optional = 4;
|
||||
}
|
||||
|
||||
// A single application container that you want to run within a pod.
|
||||
@ -3106,6 +3118,10 @@ message Secret {
|
||||
message SecretEnvSource {
|
||||
// The Secret to select from.
|
||||
optional LocalObjectReference localObjectReference = 1;
|
||||
|
||||
// Specify whether the Secret must be defined
|
||||
// +optional
|
||||
optional bool optional = 2;
|
||||
}
|
||||
|
||||
// SecretKeySelector selects a key of a Secret.
|
||||
@ -3115,6 +3131,10 @@ message SecretKeySelector {
|
||||
|
||||
// The key of the secret to select from. Must be a valid secret key.
|
||||
optional string key = 2;
|
||||
|
||||
// Specify whether the Secret or it's key must be defined
|
||||
// +optional
|
||||
optional bool optional = 3;
|
||||
}
|
||||
|
||||
// SecretList is a list of Secret.
|
||||
@ -3145,8 +3165,8 @@ message SecretVolumeSource {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the Secret,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
repeated KeyToPath items = 2;
|
||||
|
||||
@ -3157,6 +3177,10 @@ message SecretVolumeSource {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
optional int32 defaultMode = 3;
|
||||
|
||||
// Specify whether the Secret or it's keys must be defined
|
||||
// +optional
|
||||
optional bool optional = 4;
|
||||
}
|
||||
|
||||
// SecurityContext holds security configuration that will be applied to a container.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -924,8 +924,8 @@ type SecretVolumeSource struct {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the Secret,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
Items []KeyToPath `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"`
|
||||
// Optional: mode bits to use on created files by default. Must be a
|
||||
@ -935,6 +935,9 @@ type SecretVolumeSource struct {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"bytes,3,opt,name=defaultMode"`
|
||||
// Specify whether the Secret or it's keys must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,4,opt,name=optional"`
|
||||
}
|
||||
|
||||
const (
|
||||
@ -1081,8 +1084,8 @@ type ConfigMapVolumeSource struct {
|
||||
// key and content is the value. If specified, the listed keys will be
|
||||
// projected into the specified paths, and unlisted keys will not be
|
||||
// present. If a key is specified which is not present in the ConfigMap,
|
||||
// the volume setup will error. Paths must be relative and may not contain
|
||||
// the '..' path or start with '..'.
|
||||
// the volume setup will error unless it is marked optional. Paths must be
|
||||
// relative and may not contain the '..' path or start with '..'.
|
||||
// +optional
|
||||
Items []KeyToPath `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"`
|
||||
// Optional: mode bits to use on created files by default. Must be a
|
||||
@ -1092,6 +1095,9 @@ type ConfigMapVolumeSource struct {
|
||||
// mode, like fsGroup, and the result can be other mode bits set.
|
||||
// +optional
|
||||
DefaultMode *int32 `json:"defaultMode,omitempty" protobuf:"varint,3,opt,name=defaultMode"`
|
||||
// Specify whether the ConfigMap or it's keys must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,4,opt,name=optional"`
|
||||
}
|
||||
|
||||
const (
|
||||
@ -1225,6 +1231,9 @@ type ConfigMapKeySelector struct {
|
||||
LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
|
||||
// The key to select.
|
||||
Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
|
||||
// Specify whether the ConfigMap or it's key must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,3,opt,name=optional"`
|
||||
}
|
||||
|
||||
// SecretKeySelector selects a key of a Secret.
|
||||
@ -1233,6 +1242,9 @@ type SecretKeySelector struct {
|
||||
LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
|
||||
// The key of the secret to select from. Must be a valid secret key.
|
||||
Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
|
||||
// Specify whether the Secret or it's key must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,3,opt,name=optional"`
|
||||
}
|
||||
|
||||
// EnvFromSource represents the source of a set of ConfigMaps
|
||||
@ -1256,6 +1268,9 @@ type EnvFromSource struct {
|
||||
type ConfigMapEnvSource struct {
|
||||
// The ConfigMap to select from.
|
||||
LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
|
||||
// Specify whether the ConfigMap must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,2,opt,name=optional"`
|
||||
}
|
||||
|
||||
// SecretEnvSource selects a Secret to populate the environment
|
||||
@ -1266,6 +1281,9 @@ type ConfigMapEnvSource struct {
|
||||
type SecretEnvSource struct {
|
||||
// The Secret to select from.
|
||||
LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
|
||||
// Specify whether the Secret must be defined
|
||||
// +optional
|
||||
Optional *bool `json:"optional,omitempty" protobuf:"varint,2,opt,name=optional"`
|
||||
}
|
||||
|
||||
// HTTPHeader describes a custom header to be used in HTTP probes
|
||||
|
@ -181,7 +181,8 @@ func (ConfigMap) SwaggerDoc() map[string]string {
|
||||
}
|
||||
|
||||
var map_ConfigMapEnvSource = map[string]string{
|
||||
"": "ConfigMapEnvSource selects a ConfigMap to populate the environment variables with.\n\nThe contents of the target ConfigMap's Data field will represent the key-value pairs as environment variables.",
|
||||
"": "ConfigMapEnvSource selects a ConfigMap to populate the environment variables with.\n\nThe contents of the target ConfigMap's Data field will represent the key-value pairs as environment variables.",
|
||||
"optional": "Specify whether the ConfigMap must be defined",
|
||||
}
|
||||
|
||||
func (ConfigMapEnvSource) SwaggerDoc() map[string]string {
|
||||
@ -189,8 +190,9 @@ func (ConfigMapEnvSource) SwaggerDoc() map[string]string {
|
||||
}
|
||||
|
||||
var map_ConfigMapKeySelector = map[string]string{
|
||||
"": "Selects a key from a ConfigMap.",
|
||||
"key": "The key to select.",
|
||||
"": "Selects a key from a ConfigMap.",
|
||||
"key": "The key to select.",
|
||||
"optional": "Specify whether the ConfigMap or it's key must be defined",
|
||||
}
|
||||
|
||||
func (ConfigMapKeySelector) SwaggerDoc() map[string]string {
|
||||
@ -209,8 +211,9 @@ func (ConfigMapList) SwaggerDoc() map[string]string {
|
||||
|
||||
var map_ConfigMapVolumeSource = map[string]string{
|
||||
"": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.",
|
||||
"items": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"items": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"defaultMode": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
|
||||
"optional": "Specify whether the ConfigMap or it's keys must be defined",
|
||||
}
|
||||
|
||||
func (ConfigMapVolumeSource) SwaggerDoc() map[string]string {
|
||||
@ -1600,7 +1603,8 @@ func (Secret) SwaggerDoc() map[string]string {
|
||||
}
|
||||
|
||||
var map_SecretEnvSource = map[string]string{
|
||||
"": "SecretEnvSource selects a Secret to populate the environment variables with.\n\nThe contents of the target Secret's Data field will represent the key-value pairs as environment variables.",
|
||||
"": "SecretEnvSource selects a Secret to populate the environment variables with.\n\nThe contents of the target Secret's Data field will represent the key-value pairs as environment variables.",
|
||||
"optional": "Specify whether the Secret must be defined",
|
||||
}
|
||||
|
||||
func (SecretEnvSource) SwaggerDoc() map[string]string {
|
||||
@ -1608,8 +1612,9 @@ func (SecretEnvSource) SwaggerDoc() map[string]string {
|
||||
}
|
||||
|
||||
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.",
|
||||
"": "SecretKeySelector selects a key of a Secret.",
|
||||
"key": "The key of the secret to select from. Must be a valid secret key.",
|
||||
"optional": "Specify whether the Secret or it's key must be defined",
|
||||
}
|
||||
|
||||
func (SecretKeySelector) SwaggerDoc() map[string]string {
|
||||
@ -1629,8 +1634,9 @@ 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": "Name of the secret in the pod's namespace to use. More info: http://kubernetes.io/docs/user-guide/volumes#secrets",
|
||||
"items": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"items": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
"defaultMode": "Optional: mode bits to use on created files by default. Must be a value between 0 and 0777. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.",
|
||||
"optional": "Specify whether the Secret or it's keys must be defined",
|
||||
}
|
||||
|
||||
func (SecretVolumeSource) SwaggerDoc() map[string]string {
|
||||
|
@ -674,6 +674,7 @@ func autoConvert_v1_ConfigMapEnvSource_To_api_ConfigMapEnvSource(in *ConfigMapEn
|
||||
if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -685,6 +686,7 @@ func autoConvert_api_ConfigMapEnvSource_To_v1_ConfigMapEnvSource(in *api.ConfigM
|
||||
if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -697,6 +699,7 @@ func autoConvert_v1_ConfigMapKeySelector_To_api_ConfigMapKeySelector(in *ConfigM
|
||||
return err
|
||||
}
|
||||
out.Key = in.Key
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -709,6 +712,7 @@ func autoConvert_api_ConfigMapKeySelector_To_v1_ConfigMapKeySelector(in *api.Con
|
||||
return err
|
||||
}
|
||||
out.Key = in.Key
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -742,6 +746,7 @@ func autoConvert_v1_ConfigMapVolumeSource_To_api_ConfigMapVolumeSource(in *Confi
|
||||
}
|
||||
out.Items = *(*[]api.KeyToPath)(unsafe.Pointer(&in.Items))
|
||||
out.DefaultMode = (*int32)(unsafe.Pointer(in.DefaultMode))
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -755,6 +760,7 @@ func autoConvert_api_ConfigMapVolumeSource_To_v1_ConfigMapVolumeSource(in *api.C
|
||||
}
|
||||
out.Items = *(*[]KeyToPath)(unsafe.Pointer(&in.Items))
|
||||
out.DefaultMode = (*int32)(unsafe.Pointer(in.DefaultMode))
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3790,6 +3796,7 @@ func autoConvert_v1_SecretEnvSource_To_api_SecretEnvSource(in *SecretEnvSource,
|
||||
if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3801,6 +3808,7 @@ func autoConvert_api_SecretEnvSource_To_v1_SecretEnvSource(in *api.SecretEnvSour
|
||||
if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.LocalObjectReference, &out.LocalObjectReference, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3813,6 +3821,7 @@ func autoConvert_v1_SecretKeySelector_To_api_SecretKeySelector(in *SecretKeySele
|
||||
return err
|
||||
}
|
||||
out.Key = in.Key
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3825,6 +3834,7 @@ func autoConvert_api_SecretKeySelector_To_v1_SecretKeySelector(in *api.SecretKey
|
||||
return err
|
||||
}
|
||||
out.Key = in.Key
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3876,6 +3886,7 @@ func autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolum
|
||||
out.SecretName = in.SecretName
|
||||
out.Items = *(*[]api.KeyToPath)(unsafe.Pointer(&in.Items))
|
||||
out.DefaultMode = (*int32)(unsafe.Pointer(in.DefaultMode))
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -3887,6 +3898,7 @@ func autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretV
|
||||
out.SecretName = in.SecretName
|
||||
out.Items = *(*[]KeyToPath)(unsafe.Pointer(&in.Items))
|
||||
out.DefaultMode = (*int32)(unsafe.Pointer(in.DefaultMode))
|
||||
out.Optional = (*bool)(unsafe.Pointer(in.Optional))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -431,6 +431,11 @@ func DeepCopy_v1_ConfigMapEnvSource(in interface{}, out interface{}, c *conversi
|
||||
in := in.(*ConfigMapEnvSource)
|
||||
out := out.(*ConfigMapEnvSource)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -440,6 +445,11 @@ func DeepCopy_v1_ConfigMapKeySelector(in interface{}, out interface{}, c *conver
|
||||
in := in.(*ConfigMapKeySelector)
|
||||
out := out.(*ConfigMapKeySelector)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -481,6 +491,11 @@ func DeepCopy_v1_ConfigMapVolumeSource(in interface{}, out interface{}, c *conve
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -861,12 +876,16 @@ func DeepCopy_v1_EnvFromSource(in interface{}, out interface{}, c *conversion.Cl
|
||||
if in.ConfigMapRef != nil {
|
||||
in, out := &in.ConfigMapRef, &out.ConfigMapRef
|
||||
*out = new(ConfigMapEnvSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_ConfigMapEnvSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(SecretEnvSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_SecretEnvSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -908,12 +927,16 @@ func DeepCopy_v1_EnvVarSource(in interface{}, out interface{}, c *conversion.Clo
|
||||
if in.ConfigMapKeyRef != nil {
|
||||
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
|
||||
*out = new(ConfigMapKeySelector)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_ConfigMapKeySelector(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.SecretKeyRef != nil {
|
||||
in, out := &in.SecretKeyRef, &out.SecretKeyRef
|
||||
*out = new(SecretKeySelector)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_SecretKeySelector(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -2759,6 +2782,11 @@ func DeepCopy_v1_SecretEnvSource(in interface{}, out interface{}, c *conversion.
|
||||
in := in.(*SecretEnvSource)
|
||||
out := out.(*SecretEnvSource)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -2768,6 +2796,11 @@ func DeepCopy_v1_SecretKeySelector(in interface{}, out interface{}, c *conversio
|
||||
in := in.(*SecretKeySelector)
|
||||
out := out.(*SecretKeySelector)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -2809,6 +2842,11 @@ func DeepCopy_v1_SecretVolumeSource(in interface{}, out interface{}, c *conversi
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -434,6 +434,11 @@ func DeepCopy_api_ConfigMapEnvSource(in interface{}, out interface{}, c *convers
|
||||
in := in.(*ConfigMapEnvSource)
|
||||
out := out.(*ConfigMapEnvSource)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -443,6 +448,11 @@ func DeepCopy_api_ConfigMapKeySelector(in interface{}, out interface{}, c *conve
|
||||
in := in.(*ConfigMapKeySelector)
|
||||
out := out.(*ConfigMapKeySelector)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -484,6 +494,11 @@ func DeepCopy_api_ConfigMapVolumeSource(in interface{}, out interface{}, c *conv
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -889,12 +904,16 @@ func DeepCopy_api_EnvFromSource(in interface{}, out interface{}, c *conversion.C
|
||||
if in.ConfigMapRef != nil {
|
||||
in, out := &in.ConfigMapRef, &out.ConfigMapRef
|
||||
*out = new(ConfigMapEnvSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_ConfigMapEnvSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(SecretEnvSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_SecretEnvSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -936,12 +955,16 @@ func DeepCopy_api_EnvVarSource(in interface{}, out interface{}, c *conversion.Cl
|
||||
if in.ConfigMapKeyRef != nil {
|
||||
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
|
||||
*out = new(ConfigMapKeySelector)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_ConfigMapKeySelector(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.SecretKeyRef != nil {
|
||||
in, out := &in.SecretKeyRef, &out.SecretKeyRef
|
||||
*out = new(SecretKeySelector)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_SecretKeySelector(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -2791,6 +2814,11 @@ func DeepCopy_api_SecretEnvSource(in interface{}, out interface{}, c *conversion
|
||||
in := in.(*SecretEnvSource)
|
||||
out := out.(*SecretEnvSource)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -2800,6 +2828,11 @@ func DeepCopy_api_SecretKeySelector(in interface{}, out interface{}, c *conversi
|
||||
in := in.(*SecretKeySelector)
|
||||
out := out.(*SecretKeySelector)
|
||||
*out = *in
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -2841,6 +2874,11 @@ func DeepCopy_api_SecretVolumeSource(in interface{}, out interface{}, c *convers
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Optional != nil {
|
||||
in, out := &in.Optional, &out.Optional
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -933,6 +933,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the ConfigMap must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -957,6 +964,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the ConfigMap or it's key must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key"},
|
||||
},
|
||||
@ -1022,7 +1036,7 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
Description: "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
@ -1040,6 +1054,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the ConfigMap or it's keys must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -7430,6 +7451,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the Secret must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -7454,6 +7482,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the Secret or it's key must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"key"},
|
||||
},
|
||||
@ -7519,7 +7554,7 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
Description: "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
@ -7537,6 +7572,13 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"optional": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Specify whether the Secret or it's keys must be defined",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -650,13 +650,19 @@ func printGitRepoVolumeSource(git *api.GitRepoVolumeSource, w *PrefixWriter) {
|
||||
}
|
||||
|
||||
func printSecretVolumeSource(secret *api.SecretVolumeSource, w *PrefixWriter) {
|
||||
optional := secret.Optional != nil && *secret.Optional
|
||||
w.Write(LEVEL_2, "Type:\tSecret (a volume populated by a Secret)\n"+
|
||||
" SecretName:\t%v\n", secret.SecretName)
|
||||
" SecretName:\t%v\n",
|
||||
" Optional:\t%v\n",
|
||||
secret.SecretName, optional)
|
||||
}
|
||||
|
||||
func printConfigMapVolumeSource(configMap *api.ConfigMapVolumeSource, w *PrefixWriter) {
|
||||
optional := configMap.Optional != nil && *configMap.Optional
|
||||
w.Write(LEVEL_2, "Type:\tConfigMap (a volume populated by a ConfigMap)\n"+
|
||||
" Name:\t%v\n", configMap.Name)
|
||||
" Name:\t%v\n"+
|
||||
" Optional:\t%v\n",
|
||||
configMap.Name, optional)
|
||||
}
|
||||
|
||||
func printNFSVolumeSource(nfs *api.NFSVolumeSource, w *PrefixWriter) {
|
||||
@ -1037,9 +1043,11 @@ func describeContainerEnvVars(container api.Container, resolverFn EnvVarResolver
|
||||
}
|
||||
w.Write(LEVEL_3, "%s:\t%s (%s)\n", e.Name, valueFrom, resource)
|
||||
case e.ValueFrom.SecretKeyRef != nil:
|
||||
w.Write(LEVEL_3, "%s:\t<set to the key '%s' in secret '%s'>\n", e.Name, e.ValueFrom.SecretKeyRef.Key, e.ValueFrom.SecretKeyRef.Name)
|
||||
optional := e.ValueFrom.SecretKeyRef.Optional != nil && *e.ValueFrom.SecretKeyRef.Optional
|
||||
w.Write(LEVEL_3, "%s:\t<set to the key '%s' in secret '%s'>\tOptional: %t\n", e.Name, e.ValueFrom.SecretKeyRef.Key, e.ValueFrom.SecretKeyRef.Name, optional)
|
||||
case e.ValueFrom.ConfigMapKeyRef != nil:
|
||||
w.Write(LEVEL_3, "%s:\t<set to the key '%s' of config map '%s'>\n", e.Name, e.ValueFrom.ConfigMapKeyRef.Key, e.ValueFrom.ConfigMapKeyRef.Name)
|
||||
optional := e.ValueFrom.ConfigMapKeyRef.Optional != nil && *e.ValueFrom.ConfigMapKeyRef.Optional
|
||||
w.Write(LEVEL_3, "%s:\t<set to the key '%s' of config map '%s'>\tOptional: %t\n", e.Name, e.ValueFrom.ConfigMapKeyRef.Key, e.ValueFrom.ConfigMapKeyRef.Name, optional)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1054,17 +1062,20 @@ func describeContainerEnvFrom(container api.Container, resolverFn EnvVarResolver
|
||||
for _, e := range container.EnvFrom {
|
||||
from := ""
|
||||
name := ""
|
||||
optional := false
|
||||
if e.ConfigMapRef != nil {
|
||||
from = "ConfigMap"
|
||||
name = e.ConfigMapRef.Name
|
||||
optional = e.ConfigMapRef.Optional != nil && *e.ConfigMapRef.Optional
|
||||
} else if e.SecretRef != nil {
|
||||
from = "Secret"
|
||||
name = e.SecretRef.Name
|
||||
optional = e.SecretRef.Optional != nil && *e.SecretRef.Optional
|
||||
}
|
||||
if len(e.Prefix) == 0 {
|
||||
w.Write(LEVEL_3, "%s\t%s\n", name, from)
|
||||
w.Write(LEVEL_3, "%s\t%s\tOptional: %t\n", name, from, optional)
|
||||
} else {
|
||||
w.Write(LEVEL_3, "%s\t%s with prefix '%s'\n", name, from, e.Prefix)
|
||||
w.Write(LEVEL_3, "%s\t%s with prefix '%s'\tOptional: %t\n", name, from, e.Prefix, optional)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ func VerifyDatesInOrder(
|
||||
}
|
||||
|
||||
func TestDescribeContainers(t *testing.T) {
|
||||
trueVal := true
|
||||
testCases := []struct {
|
||||
container api.Container
|
||||
status api.ContainerStatus
|
||||
@ -295,7 +296,7 @@ func TestDescribeContainers(t *testing.T) {
|
||||
Ready: true,
|
||||
RestartCount: 7,
|
||||
},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tConfigMap"},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tConfigMap\tOptional: false"},
|
||||
},
|
||||
{
|
||||
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"}}}}},
|
||||
@ -304,16 +305,25 @@ func TestDescribeContainers(t *testing.T) {
|
||||
Ready: true,
|
||||
RestartCount: 7,
|
||||
},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tConfigMap with prefix 'p_'"},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tConfigMap with prefix 'p_'\tOptional: false"},
|
||||
},
|
||||
{
|
||||
container: api.Container{Name: "test", Image: "image", Env: []api.EnvVar{{Name: "envname", Value: "xyz"}}, EnvFrom: []api.EnvFromSource{{SecretRef: &api.SecretEnvSource{LocalObjectReference: api.LocalObjectReference{Name: "a123"}}}}},
|
||||
container: api.Container{Name: "test", Image: "image", Env: []api.EnvVar{{Name: "envname", Value: "xyz"}}, EnvFrom: []api.EnvFromSource{{ConfigMapRef: &api.ConfigMapEnvSource{Optional: &trueVal, 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\tSecret"},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tConfigMap\tOptional: true"},
|
||||
},
|
||||
{
|
||||
container: api.Container{Name: "test", Image: "image", Env: []api.EnvVar{{Name: "envname", Value: "xyz"}}, EnvFrom: []api.EnvFromSource{{SecretRef: &api.SecretEnvSource{LocalObjectReference: api.LocalObjectReference{Name: "a123"}, Optional: &trueVal}}}},
|
||||
status: api.ContainerStatus{
|
||||
Name: "test",
|
||||
Ready: true,
|
||||
RestartCount: 7,
|
||||
},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tSecret\tOptional: true"},
|
||||
},
|
||||
{
|
||||
container: api.Container{Name: "test", Image: "image", Env: []api.EnvVar{{Name: "envname", Value: "xyz"}}, EnvFrom: []api.EnvFromSource{{Prefix: "p_", SecretRef: &api.SecretEnvSource{LocalObjectReference: api.LocalObjectReference{Name: "a123"}}}}},
|
||||
@ -322,7 +332,7 @@ func TestDescribeContainers(t *testing.T) {
|
||||
Ready: true,
|
||||
RestartCount: 7,
|
||||
},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tSecret with prefix 'p_'"},
|
||||
expectedElements: []string{"test", "State", "Waiting", "Ready", "True", "Restart Count", "7", "Image", "image", "envname", "xyz", "a123\tSecret with prefix 'p_'\tOptional: false"},
|
||||
},
|
||||
// Command
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@ -427,14 +428,20 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
||||
for _, envFrom := range container.EnvFrom {
|
||||
switch {
|
||||
case envFrom.ConfigMapRef != nil:
|
||||
name := envFrom.ConfigMapRef.Name
|
||||
cm := envFrom.ConfigMapRef
|
||||
name := cm.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)
|
||||
}
|
||||
optional := cm.Optional != nil && *cm.Optional
|
||||
configMap, err = kl.kubeClient.Core().ConfigMaps(pod.Namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && optional {
|
||||
// ignore error when marked optional
|
||||
continue
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
configMaps[name] = configMap
|
||||
@ -450,14 +457,20 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
||||
tmpEnv[k] = v
|
||||
}
|
||||
case envFrom.SecretRef != nil:
|
||||
name := envFrom.SecretRef.Name
|
||||
s := envFrom.SecretRef
|
||||
name := s.Name
|
||||
secret, ok := secrets[name]
|
||||
if !ok {
|
||||
if kl.kubeClient == nil {
|
||||
return result, fmt.Errorf("Couldn't get secret %v/%v, no kubeClient defined", pod.Namespace, name)
|
||||
}
|
||||
optional := s.Optional != nil && *s.Optional
|
||||
secret, err = kl.kubeClient.Core().Secrets(pod.Namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && optional {
|
||||
// ignore error when marked optional
|
||||
continue
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
secrets[name] = secret
|
||||
@ -510,8 +523,10 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
||||
return result, err
|
||||
}
|
||||
case envVar.ValueFrom.ConfigMapKeyRef != nil:
|
||||
name := envVar.ValueFrom.ConfigMapKeyRef.Name
|
||||
key := envVar.ValueFrom.ConfigMapKeyRef.Key
|
||||
cm := envVar.ValueFrom.ConfigMapKeyRef
|
||||
name := cm.Name
|
||||
key := cm.Key
|
||||
optional := cm.Optional != nil && *cm.Optional
|
||||
configMap, ok := configMaps[name]
|
||||
if !ok {
|
||||
if kl.kubeClient == nil {
|
||||
@ -519,17 +534,26 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
||||
}
|
||||
configMap, err = kl.kubeClient.Core().ConfigMaps(pod.Namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && optional {
|
||||
// ignore error when marked optional
|
||||
continue
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
configMaps[name] = configMap
|
||||
}
|
||||
runtimeVal, ok = configMap.Data[key]
|
||||
if !ok {
|
||||
if optional {
|
||||
continue
|
||||
}
|
||||
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
|
||||
s := envVar.ValueFrom.SecretKeyRef
|
||||
name := s.Name
|
||||
key := s.Key
|
||||
optional := s.Optional != nil && *s.Optional
|
||||
secret, ok := secrets[name]
|
||||
if !ok {
|
||||
if kl.kubeClient == nil {
|
||||
@ -537,17 +561,30 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
||||
}
|
||||
secret, err = kl.secretManager.GetSecret(pod.Namespace, name)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && optional {
|
||||
// ignore error when marked optional
|
||||
continue
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
secrets[name] = secret
|
||||
}
|
||||
runtimeValBytes, ok := secret.Data[key]
|
||||
if !ok {
|
||||
if optional {
|
||||
continue
|
||||
}
|
||||
return result, fmt.Errorf("Couldn't find key %v in Secret %v/%v", key, pod.Namespace, name)
|
||||
}
|
||||
runtimeVal = string(runtimeValBytes)
|
||||
}
|
||||
}
|
||||
// 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, envVar.Name)
|
||||
|
||||
tmpEnv[envVar.Name] = runtimeVal
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -257,6 +258,7 @@ func buildService(name, namespace, clusterIP, protocol string, port int) *v1.Ser
|
||||
}
|
||||
|
||||
func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
trueVal := true
|
||||
services := []*v1.Service{
|
||||
buildService("kubernetes", metav1.NamespaceDefault, "1.2.3.1", "TCP", 8081),
|
||||
buildService("test", "test1", "1.2.3.3", "TCP", 8083),
|
||||
@ -616,6 +618,106 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "configmapkeyref_missing_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "missing-config-map"},
|
||||
Key: "key",
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "configmapkeyref_missing_key_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
ConfigMapKeyRef: &v1.ConfigMapKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "test-config-map"},
|
||||
Key: "key",
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
nilLister: true,
|
||||
configMap: &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "test1",
|
||||
Name: "test-configmap",
|
||||
},
|
||||
Data: map[string]string{
|
||||
"a": "b",
|
||||
},
|
||||
},
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "secretkeyref_missing_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
SecretKeyRef: &v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "missing-secret"},
|
||||
Key: "key",
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "secretkeyref_missing_key_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
SecretKeyRef: &v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "test-secret"},
|
||||
Key: "key",
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
nilLister: true,
|
||||
secret: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "test1",
|
||||
Name: "test-secret",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"a": []byte("b"),
|
||||
},
|
||||
},
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "configmap",
|
||||
ns: "test1",
|
||||
@ -722,6 +824,19 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
masterServiceNs: "nothing",
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap_missing_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
EnvFrom: []v1.EnvFromSource{
|
||||
{ConfigMapRef: &v1.ConfigMapEnvSource{
|
||||
Optional: &trueVal,
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "missing-config-map"}}},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "configmap_invalid_keys",
|
||||
ns: "test1",
|
||||
@ -876,6 +991,19 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
masterServiceNs: "nothing",
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "secret_missing_optional",
|
||||
ns: "test",
|
||||
container: &v1.Container{
|
||||
EnvFrom: []v1.EnvFromSource{
|
||||
{SecretRef: &v1.SecretEnvSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "missing-secret"},
|
||||
Optional: &trueVal}},
|
||||
},
|
||||
},
|
||||
masterServiceNs: "nothing",
|
||||
expectedEnvs: nil,
|
||||
},
|
||||
{
|
||||
name: "secret_invalid_keys",
|
||||
ns: "test1",
|
||||
@ -940,10 +1068,17 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
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")
|
||||
err = apierrors.NewNotFound(action.GetResource().GroupResource(), "configmap-name")
|
||||
}
|
||||
return true, tc.configMap, err
|
||||
})
|
||||
testKubelet.fakeKubeClient.AddReactor("get", "secrets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
var err error
|
||||
if tc.secret == nil {
|
||||
err = apierrors.NewNotFound(action.GetResource().GroupResource(), "secret-name")
|
||||
}
|
||||
return true, tc.secret, err
|
||||
})
|
||||
|
||||
testKubelet.fakeKubeClient.AddReactor("get", "secrets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
var err error
|
||||
|
@ -173,8 +173,12 @@ func newTestKubeletWithImageList(
|
||||
kubelet.cadvisor = mockCadvisor
|
||||
|
||||
fakeMirrorClient := podtest.NewFakeMirrorClient()
|
||||
fakeSecretManager := secret.NewFakeManager()
|
||||
kubelet.podManager = kubepod.NewBasicPodManager(fakeMirrorClient, fakeSecretManager)
|
||||
secretManager, err := secret.NewSimpleSecretManager(kubelet.kubeClient)
|
||||
if err != nil {
|
||||
t.Fatalf("can't create a secret manager: %v", err)
|
||||
}
|
||||
kubelet.secretManager = secretManager
|
||||
kubelet.podManager = kubepod.NewBasicPodManager(fakeMirrorClient, kubelet.secretManager)
|
||||
kubelet.statusManager = status.NewManager(fakeKubeClient, kubelet.podManager)
|
||||
kubelet.containerRefManager = kubecontainer.NewRefManager()
|
||||
diskSpaceManager, err := newDiskSpaceManager(mockCadvisor, DiskSpacePolicy{})
|
||||
@ -249,7 +253,7 @@ func newTestKubeletWithImageList(
|
||||
|
||||
plug := &volumetest.FakeVolumePlugin{PluginName: "fake", Host: nil}
|
||||
kubelet.volumePluginMgr, err =
|
||||
NewInitializedVolumePluginMgr(kubelet, fakeSecretManager, []volume.VolumePlugin{plug})
|
||||
NewInitializedVolumePluginMgr(kubelet, kubelet.secretManager, []volume.VolumePlugin{plug})
|
||||
require.NoError(t, err, "Failed to initialize VolumePluginMgr")
|
||||
|
||||
kubelet.mounter = &mount.FakeMounter{}
|
||||
|
@ -23,6 +23,7 @@ go_library(
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||
],
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
@ -170,10 +171,19 @@ func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
return fmt.Errorf("Cannot setup configMap volume %v because kube client is not configured", b.volName)
|
||||
}
|
||||
|
||||
optional := b.source.Optional != nil && *b.source.Optional
|
||||
configMap, err := kubeClient.Core().ConfigMaps(b.pod.Namespace).Get(b.source.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorf("Couldn't get configMap %v/%v: %v", b.pod.Namespace, b.source.Name, err)
|
||||
return err
|
||||
if !(errors.IsNotFound(err) && optional) {
|
||||
glog.Errorf("Couldn't get configMap %v/%v: %v", b.pod.Namespace, b.source.Name, err)
|
||||
return err
|
||||
}
|
||||
configMap = &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: b.pod.Namespace,
|
||||
Name: b.source.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
totalBytes := totalBytes(configMap)
|
||||
@ -183,7 +193,7 @@ func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
len(configMap.Data),
|
||||
totalBytes)
|
||||
|
||||
payload, err := makePayload(b.source.Items, configMap, b.source.DefaultMode)
|
||||
payload, err := makePayload(b.source.Items, configMap, b.source.DefaultMode, optional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -210,7 +220,7 @@ func (b *configMapVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makePayload(mappings []v1.KeyToPath, configMap *v1.ConfigMap, defaultMode *int32) (map[string]volumeutil.FileProjection, error) {
|
||||
func makePayload(mappings []v1.KeyToPath, configMap *v1.ConfigMap, defaultMode *int32, optional bool) (map[string]volumeutil.FileProjection, error) {
|
||||
if defaultMode == nil {
|
||||
return nil, fmt.Errorf("No defaultMode used, not even the default value for it")
|
||||
}
|
||||
@ -228,6 +238,9 @@ func makePayload(mappings []v1.KeyToPath, configMap *v1.ConfigMap, defaultMode *
|
||||
for _, ktp := range mappings {
|
||||
content, ok := configMap.Data[ktp.Key]
|
||||
if !ok {
|
||||
if optional {
|
||||
continue
|
||||
}
|
||||
err_msg := "references non-existent config key"
|
||||
glog.Errorf(err_msg)
|
||||
return nil, fmt.Errorf(err_msg)
|
||||
|
@ -43,6 +43,7 @@ func TestMakePayload(t *testing.T) {
|
||||
mappings []v1.KeyToPath
|
||||
configMap *v1.ConfigMap
|
||||
mode int32
|
||||
optional bool
|
||||
payload map[string]util.FileProjection
|
||||
success bool
|
||||
}{
|
||||
@ -215,10 +216,29 @@ func TestMakePayload(t *testing.T) {
|
||||
},
|
||||
success: true,
|
||||
},
|
||||
{
|
||||
name: "optional non existent key",
|
||||
mappings: []v1.KeyToPath{
|
||||
{
|
||||
Key: "zab",
|
||||
Path: "path/to/foo.txt",
|
||||
},
|
||||
},
|
||||
configMap: &v1.ConfigMap{
|
||||
Data: map[string]string{
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
},
|
||||
},
|
||||
mode: 0644,
|
||||
optional: true,
|
||||
payload: map[string]util.FileProjection{},
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
actualPayload, err := makePayload(tc.mappings, tc.configMap, &tc.mode)
|
||||
actualPayload, err := makePayload(tc.mappings, tc.configMap, &tc.mode, tc.optional)
|
||||
if err != nil && tc.success {
|
||||
t.Errorf("%v: unexpected failure making payload: %v", tc.name, err)
|
||||
continue
|
||||
@ -388,6 +408,143 @@ func TestPluginReboot(t *testing.T) {
|
||||
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
}
|
||||
|
||||
func TestPluginOptional(t *testing.T) {
|
||||
var (
|
||||
testPodUID = types.UID("test_pod_uid")
|
||||
testVolumeName = "test_volume_name"
|
||||
testNamespace = "test_configmap_namespace"
|
||||
testName = "test_configmap_name"
|
||||
trueVal = true
|
||||
|
||||
volumeSpec = volumeSpec(testVolumeName, testName, 0644)
|
||||
client = fake.NewSimpleClientset()
|
||||
pluginMgr = volume.VolumePluginMgr{}
|
||||
tempDir, host = newTestHost(t, client)
|
||||
)
|
||||
volumeSpec.VolumeSource.ConfigMap.Optional = &trueVal
|
||||
|
||||
defer os.RemoveAll(tempDir)
|
||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||
|
||||
plugin, err := pluginMgr.FindPluginByName(configMapPluginName)
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}}
|
||||
mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Errorf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
vName, err := plugin.GetVolumeName(volume.NewSpecFromVolume(volumeSpec))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to GetVolumeName: %v", err)
|
||||
}
|
||||
if vName != "test_volume_name/test_configmap_name" {
|
||||
t.Errorf("Got unexpect VolumeName %v", vName)
|
||||
}
|
||||
|
||||
volumePath := mounter.GetPath()
|
||||
if !strings.HasSuffix(volumePath, fmt.Sprintf("pods/test_pod_uid/volumes/kubernetes.io~configmap/test_volume_name")) {
|
||||
t.Errorf("Got unexpected path: %s", volumePath)
|
||||
}
|
||||
|
||||
fsGroup := int64(1001)
|
||||
err = mounter.SetUp(&fsGroup)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to setup volume: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(volumePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, volume path not created: %s", volumePath)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
infos, err := ioutil.ReadDir(volumePath)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't find volume path, %s", volumePath)
|
||||
}
|
||||
if len(infos) != 0 {
|
||||
t.Errorf("empty directory, %s, not found", volumePath)
|
||||
}
|
||||
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
}
|
||||
|
||||
func TestPluginKeysOptional(t *testing.T) {
|
||||
var (
|
||||
testPodUID = types.UID("test_pod_uid")
|
||||
testVolumeName = "test_volume_name"
|
||||
testNamespace = "test_configmap_namespace"
|
||||
testName = "test_configmap_name"
|
||||
trueVal = true
|
||||
|
||||
volumeSpec = volumeSpec(testVolumeName, testName, 0644)
|
||||
configMap = configMap(testNamespace, testName)
|
||||
client = fake.NewSimpleClientset(&configMap)
|
||||
pluginMgr = volume.VolumePluginMgr{}
|
||||
tempDir, host = newTestHost(t, client)
|
||||
)
|
||||
volumeSpec.VolumeSource.ConfigMap.Items = []v1.KeyToPath{
|
||||
{Key: "data-1", Path: "data-1"},
|
||||
{Key: "data-2", Path: "data-2"},
|
||||
{Key: "data-3", Path: "data-3"},
|
||||
{Key: "missing", Path: "missing"},
|
||||
}
|
||||
volumeSpec.VolumeSource.ConfigMap.Optional = &trueVal
|
||||
|
||||
defer os.RemoveAll(tempDir)
|
||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||
|
||||
plugin, err := pluginMgr.FindPluginByName(configMapPluginName)
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}}
|
||||
mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Errorf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
vName, err := plugin.GetVolumeName(volume.NewSpecFromVolume(volumeSpec))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to GetVolumeName: %v", err)
|
||||
}
|
||||
if vName != "test_volume_name/test_configmap_name" {
|
||||
t.Errorf("Got unexpect VolumeName %v", vName)
|
||||
}
|
||||
|
||||
volumePath := mounter.GetPath()
|
||||
if !strings.HasSuffix(volumePath, fmt.Sprintf("pods/test_pod_uid/volumes/kubernetes.io~configmap/test_volume_name")) {
|
||||
t.Errorf("Got unexpected path: %s", volumePath)
|
||||
}
|
||||
|
||||
fsGroup := int64(1001)
|
||||
err = mounter.SetUp(&fsGroup)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to setup volume: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(volumePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, volume path not created: %s", volumePath)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
doTestConfigMapDataInVolume(volumePath, configMap, t)
|
||||
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
}
|
||||
|
||||
func volumeSpec(volumeName, configMapName string, defaultMode int32) *v1.Volume {
|
||||
return &v1.Volume{
|
||||
Name: volumeName,
|
||||
|
@ -23,6 +23,8 @@ go_library(
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:k8s.io/apimachinery/pkg/api/errors",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||
],
|
||||
)
|
||||
|
@ -22,6 +22,8 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
ioutil "k8s.io/kubernetes/pkg/util/io"
|
||||
@ -191,10 +193,19 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
optional := b.source.Optional != nil && *b.source.Optional
|
||||
secret, err := b.getSecret(b.pod.Namespace, b.source.SecretName)
|
||||
if err != nil {
|
||||
glog.Errorf("Couldn't get secret %v/%v", b.pod.Namespace, b.source.SecretName)
|
||||
return err
|
||||
if !(errors.IsNotFound(err) && optional) {
|
||||
glog.Errorf("Couldn't get secret %v/%v", b.pod.Namespace, b.source.SecretName)
|
||||
return err
|
||||
}
|
||||
secret = &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: b.pod.Namespace,
|
||||
Name: b.source.SecretName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
totalBytes := totalSecretBytes(secret)
|
||||
@ -204,7 +215,7 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
len(secret.Data),
|
||||
totalBytes)
|
||||
|
||||
payload, err := makePayload(b.source.Items, secret, b.source.DefaultMode)
|
||||
payload, err := makePayload(b.source.Items, secret, b.source.DefaultMode, optional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -231,7 +242,7 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makePayload(mappings []v1.KeyToPath, secret *v1.Secret, defaultMode *int32) (map[string]volumeutil.FileProjection, error) {
|
||||
func makePayload(mappings []v1.KeyToPath, secret *v1.Secret, defaultMode *int32, optional bool) (map[string]volumeutil.FileProjection, error) {
|
||||
if defaultMode == nil {
|
||||
return nil, fmt.Errorf("No defaultMode used, not even the default value for it")
|
||||
}
|
||||
@ -249,6 +260,9 @@ func makePayload(mappings []v1.KeyToPath, secret *v1.Secret, defaultMode *int32)
|
||||
for _, ktp := range mappings {
|
||||
content, ok := secret.Data[ktp.Key]
|
||||
if !ok {
|
||||
if optional {
|
||||
continue
|
||||
}
|
||||
err_msg := "references non-existent secret key"
|
||||
glog.Errorf(err_msg)
|
||||
return nil, fmt.Errorf(err_msg)
|
||||
|
@ -46,6 +46,7 @@ func TestMakePayload(t *testing.T) {
|
||||
mappings []v1.KeyToPath
|
||||
secret *v1.Secret
|
||||
mode int32
|
||||
optional bool
|
||||
payload map[string]util.FileProjection
|
||||
success bool
|
||||
}{
|
||||
@ -218,10 +219,29 @@ func TestMakePayload(t *testing.T) {
|
||||
},
|
||||
success: true,
|
||||
},
|
||||
{
|
||||
name: "optional non existent key",
|
||||
mappings: []v1.KeyToPath{
|
||||
{
|
||||
Key: "zab",
|
||||
Path: "path/to/foo.txt",
|
||||
},
|
||||
},
|
||||
secret: &v1.Secret{
|
||||
Data: map[string][]byte{
|
||||
"foo": []byte("foo"),
|
||||
"bar": []byte("bar"),
|
||||
},
|
||||
},
|
||||
mode: 0644,
|
||||
optional: true,
|
||||
payload: map[string]util.FileProjection{},
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
actualPayload, err := makePayload(tc.mappings, tc.secret, &tc.mode)
|
||||
actualPayload, err := makePayload(tc.mappings, tc.secret, &tc.mode, tc.optional)
|
||||
if err != nil && tc.success {
|
||||
t.Errorf("%v: unexpected failure making payload: %v", tc.name, err)
|
||||
continue
|
||||
@ -398,6 +418,154 @@ func TestPluginReboot(t *testing.T) {
|
||||
doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
}
|
||||
|
||||
func TestPluginOptional(t *testing.T) {
|
||||
var (
|
||||
testPodUID = types.UID("test_pod_uid")
|
||||
testVolumeName = "test_volume_name"
|
||||
testNamespace = "test_secret_namespace"
|
||||
testName = "test_secret_name"
|
||||
trueVal = true
|
||||
|
||||
volumeSpec = volumeSpec(testVolumeName, testName, 0644)
|
||||
client = fake.NewSimpleClientset()
|
||||
pluginMgr = volume.VolumePluginMgr{}
|
||||
rootDir, host = newTestHost(t, client)
|
||||
)
|
||||
volumeSpec.Secret.Optional = &trueVal
|
||||
defer os.RemoveAll(rootDir)
|
||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||
|
||||
plugin, err := pluginMgr.FindPluginByName(secretPluginName)
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}}
|
||||
mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Errorf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
volumePath := mounter.GetPath()
|
||||
if !strings.HasSuffix(volumePath, fmt.Sprintf("pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name")) {
|
||||
t.Errorf("Got unexpected path: %s", volumePath)
|
||||
}
|
||||
|
||||
err = mounter.SetUp(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to setup volume: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(volumePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, volume path not created: %s", volumePath)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// secret volume should create its own empty wrapper path
|
||||
podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir)
|
||||
|
||||
if _, err := os.Stat(podWrapperMetadataDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
infos, err := ioutil.ReadDir(volumePath)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't find volume path, %s", volumePath)
|
||||
}
|
||||
if len(infos) != 0 {
|
||||
t.Errorf("empty directory, %s, not found", volumePath)
|
||||
}
|
||||
|
||||
defer doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
}
|
||||
|
||||
func TestPluginOptionalKeys(t *testing.T) {
|
||||
var (
|
||||
testPodUID = types.UID("test_pod_uid")
|
||||
testVolumeName = "test_volume_name"
|
||||
testNamespace = "test_secret_namespace"
|
||||
testName = "test_secret_name"
|
||||
trueVal = true
|
||||
|
||||
volumeSpec = volumeSpec(testVolumeName, testName, 0644)
|
||||
secret = secret(testNamespace, testName)
|
||||
client = fake.NewSimpleClientset(&secret)
|
||||
pluginMgr = volume.VolumePluginMgr{}
|
||||
rootDir, host = newTestHost(t, client)
|
||||
)
|
||||
volumeSpec.VolumeSource.Secret.Items = []v1.KeyToPath{
|
||||
{Key: "data-1", Path: "data-1"},
|
||||
{Key: "data-2", Path: "data-2"},
|
||||
{Key: "data-3", Path: "data-3"},
|
||||
{Key: "missing", Path: "missing"},
|
||||
}
|
||||
volumeSpec.Secret.Optional = &trueVal
|
||||
defer os.RemoveAll(rootDir)
|
||||
pluginMgr.InitPlugins(ProbeVolumePlugins(), host)
|
||||
|
||||
plugin, err := pluginMgr.FindPluginByName(secretPluginName)
|
||||
if err != nil {
|
||||
t.Errorf("Can't find the plugin by name")
|
||||
}
|
||||
|
||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, UID: testPodUID}}
|
||||
mounter, err := plugin.NewMounter(volume.NewSpecFromVolume(volumeSpec), pod, volume.VolumeOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||
}
|
||||
if mounter == nil {
|
||||
t.Errorf("Got a nil Mounter")
|
||||
}
|
||||
|
||||
volumePath := mounter.GetPath()
|
||||
if !strings.HasSuffix(volumePath, fmt.Sprintf("pods/test_pod_uid/volumes/kubernetes.io~secret/test_volume_name")) {
|
||||
t.Errorf("Got unexpected path: %s", volumePath)
|
||||
}
|
||||
|
||||
err = mounter.SetUp(nil)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to setup volume: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(volumePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, volume path not created: %s", volumePath)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// secret volume should create its own empty wrapper path
|
||||
podWrapperMetadataDir := fmt.Sprintf("%v/pods/test_pod_uid/plugins/kubernetes.io~empty-dir/wrapped_test_volume_name", rootDir)
|
||||
|
||||
if _, err := os.Stat(podWrapperMetadataDir); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Errorf("SetUp() failed, empty-dir wrapper path is not created: %s", podWrapperMetadataDir)
|
||||
} else {
|
||||
t.Errorf("SetUp() failed: %v", err)
|
||||
}
|
||||
}
|
||||
doTestSecretDataInVolume(volumePath, secret, t)
|
||||
defer doTestCleanAndTeardown(plugin, testPodUID, testVolumeName, volumePath, t)
|
||||
|
||||
// Metrics only supported on linux
|
||||
metrics, err := mounter.GetMetrics()
|
||||
if runtime.GOOS == "linux" {
|
||||
assert.NotEmpty(t, metrics)
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
t.Skipf("Volume metrics not supported on %s", runtime.GOOS)
|
||||
}
|
||||
}
|
||||
|
||||
func volumeSpec(volumeName, secretName string, defaultMode int32) *v1.Volume {
|
||||
return &v1.Volume{
|
||||
Name: volumeName,
|
||||
|
@ -19,6 +19,7 @@ package common
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -154,6 +155,189 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
|
||||
Eventually(pollLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-2"))
|
||||
})
|
||||
|
||||
It("optional updates should be reflected in volume [Conformance] [Volume]", func() {
|
||||
|
||||
// We may have to wait or a full sync period to elapse before the
|
||||
// Kubelet projects the update into the volume and the container picks
|
||||
// it up. This timeout is based on the default Kubelet sync period (1
|
||||
// minute) plus additional time for fudge factor.
|
||||
const podLogTimeout = 300 * time.Second
|
||||
trueVal := true
|
||||
|
||||
volumeMountPath := "/etc/configmap-volumes"
|
||||
|
||||
deleteName := "cm-test-opt-del-" + string(uuid.NewUUID())
|
||||
deleteContainerName := "delcm-volume-test"
|
||||
deleteVolumeName := "deletecm-volume"
|
||||
deleteConfigMap := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: deleteName,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"data-1": "value-1",
|
||||
},
|
||||
}
|
||||
|
||||
updateName := "cm-test-opt-upd-" + string(uuid.NewUUID())
|
||||
updateContainerName := "updcm-volume-test"
|
||||
updateVolumeName := "updatecm-volume"
|
||||
updateConfigMap := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: updateName,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"data-1": "value-1",
|
||||
},
|
||||
}
|
||||
|
||||
createName := "cm-test-opt-create-" + string(uuid.NewUUID())
|
||||
createContainerName := "createcm-volume-test"
|
||||
createVolumeName := "createcm-volume"
|
||||
createConfigMap := &v1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: createName,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"data-1": "value-1",
|
||||
},
|
||||
}
|
||||
|
||||
By(fmt.Sprintf("Creating configMap with name %s", deleteConfigMap.Name))
|
||||
var err error
|
||||
if deleteConfigMap, err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(deleteConfigMap); err != nil {
|
||||
framework.Failf("unable to create test configMap %s: %v", deleteConfigMap.Name, err)
|
||||
}
|
||||
|
||||
By(fmt.Sprintf("Creating configMap with name %s", updateConfigMap.Name))
|
||||
if updateConfigMap, err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(updateConfigMap); err != nil {
|
||||
framework.Failf("unable to create test configMap %s: %v", updateConfigMap.Name, err)
|
||||
}
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: deleteVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: deleteName,
|
||||
},
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: updateVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: updateName,
|
||||
},
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: createVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
ConfigMap: &v1.ConfigMapVolumeSource{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: createName,
|
||||
},
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: deleteContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/delete/data-1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: deleteVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "delete"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: updateContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/update/data-3"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: updateVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "update"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: createContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/configmap-volumes/create/data-1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: createVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "create"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyNever,
|
||||
},
|
||||
}
|
||||
By("Creating the pod")
|
||||
f.PodClient().CreateSync(pod)
|
||||
|
||||
pollCreateLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, createContainerName)
|
||||
}
|
||||
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/create/data-1"))
|
||||
|
||||
pollUpdateLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, updateContainerName)
|
||||
}
|
||||
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/update/data-3"))
|
||||
|
||||
pollDeleteLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, deleteContainerName)
|
||||
}
|
||||
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
||||
|
||||
By(fmt.Sprintf("Deleting configmap %v", deleteConfigMap.Name))
|
||||
err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Delete(deleteConfigMap.Name, &v1.DeleteOptions{})
|
||||
Expect(err).NotTo(HaveOccurred(), "Failed to delete configmap %q in namespace %q", deleteConfigMap.Name, f.Namespace.Name)
|
||||
|
||||
By(fmt.Sprintf("Updating configmap %v", updateConfigMap.Name))
|
||||
updateConfigMap.ResourceVersion = "" // to force update
|
||||
delete(updateConfigMap.Data, "data-1")
|
||||
updateConfigMap.Data["data-3"] = "value-3"
|
||||
_, err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Update(updateConfigMap)
|
||||
Expect(err).NotTo(HaveOccurred(), "Failed to update configmap %q in namespace %q", updateConfigMap.Name, f.Namespace.Name)
|
||||
|
||||
By(fmt.Sprintf("Creating configMap with name %s", createConfigMap.Name))
|
||||
if createConfigMap, err = f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(createConfigMap); err != nil {
|
||||
framework.Failf("unable to create test configMap %s: %v", createConfigMap.Name, err)
|
||||
}
|
||||
|
||||
By("waiting to observe update in volume")
|
||||
|
||||
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
||||
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-3"))
|
||||
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/delete/data-1"))
|
||||
})
|
||||
|
||||
It("should be consumable via environment variable [Conformance]", func() {
|
||||
name := "configmap-test-" + string(uuid.NewUUID())
|
||||
configMap := newConfigMap(f, name)
|
||||
|
@ -19,6 +19,8 @@ package common
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
@ -26,6 +28,7 @@ import (
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = framework.KubeDescribe("Secrets", func() {
|
||||
@ -150,6 +153,183 @@ var _ = framework.KubeDescribe("Secrets", func() {
|
||||
})
|
||||
})
|
||||
|
||||
It("optional updates should be reflected in volume [Conformance] [Volume]", func() {
|
||||
|
||||
// We may have to wait or a full sync period to elapse before the
|
||||
// Kubelet projects the update into the volume and the container picks
|
||||
// it up. This timeout is based on the default Kubelet sync period (1
|
||||
// minute) plus additional time for fudge factor.
|
||||
const podLogTimeout = 300 * time.Second
|
||||
trueVal := true
|
||||
|
||||
volumeMountPath := "/etc/secret-volumes"
|
||||
|
||||
deleteName := "s-test-opt-del-" + string(uuid.NewUUID())
|
||||
deleteContainerName := "dels-volume-test"
|
||||
deleteVolumeName := "deletes-volume"
|
||||
deleteSecret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: deleteName,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"data-1": []byte("value-1"),
|
||||
},
|
||||
}
|
||||
|
||||
updateName := "s-test-opt-upd-" + string(uuid.NewUUID())
|
||||
updateContainerName := "upds-volume-test"
|
||||
updateVolumeName := "updates-volume"
|
||||
updateSecret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: updateName,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"data-1": []byte("value-1"),
|
||||
},
|
||||
}
|
||||
|
||||
createName := "s-test-opt-create-" + string(uuid.NewUUID())
|
||||
createContainerName := "creates-volume-test"
|
||||
createVolumeName := "creates-volume"
|
||||
createSecret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: f.Namespace.Name,
|
||||
Name: createName,
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"data-1": []byte("value-1"),
|
||||
},
|
||||
}
|
||||
|
||||
By(fmt.Sprintf("Creating secret with name %s", deleteSecret.Name))
|
||||
var err error
|
||||
if deleteSecret, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Create(deleteSecret); err != nil {
|
||||
framework.Failf("unable to create test secret %s: %v", deleteSecret.Name, err)
|
||||
}
|
||||
|
||||
By(fmt.Sprintf("Creating secret with name %s", updateSecret.Name))
|
||||
if updateSecret, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Create(updateSecret); err != nil {
|
||||
framework.Failf("unable to create test secret %s: %v", updateSecret.Name, err)
|
||||
}
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-secrets-" + string(uuid.NewUUID()),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: deleteVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: deleteName,
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: updateVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: updateName,
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: createVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Secret: &v1.SecretVolumeSource{
|
||||
SecretName: createName,
|
||||
Optional: &trueVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: deleteContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/delete/data-1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: deleteVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "delete"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: updateContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/update/data-3"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: updateVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "update"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: createContainerName,
|
||||
Image: "gcr.io/google_containers/mounttest:0.7",
|
||||
Command: []string{"/mt", "--break_on_expected_content=false", "--retry_time=120", "--file_content_in_loop=/etc/secret-volumes/create/data-1"},
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: createVolumeName,
|
||||
MountPath: path.Join(volumeMountPath, "create"),
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyNever,
|
||||
},
|
||||
}
|
||||
By("Creating the pod")
|
||||
f.PodClient().CreateSync(pod)
|
||||
|
||||
pollCreateLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, createContainerName)
|
||||
}
|
||||
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/secret-volumes/create/data-1"))
|
||||
|
||||
pollUpdateLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, updateContainerName)
|
||||
}
|
||||
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/secret-volumes/update/data-3"))
|
||||
|
||||
pollDeleteLogs := func() (string, error) {
|
||||
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, deleteContainerName)
|
||||
}
|
||||
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
||||
|
||||
By(fmt.Sprintf("Deleting secret %v", deleteSecret.Name))
|
||||
err = f.ClientSet.Core().Secrets(f.Namespace.Name).Delete(deleteSecret.Name, &v1.DeleteOptions{})
|
||||
Expect(err).NotTo(HaveOccurred(), "Failed to delete secret %q in namespace %q", deleteSecret.Name, f.Namespace.Name)
|
||||
|
||||
By(fmt.Sprintf("Updating secret %v", updateSecret.Name))
|
||||
updateSecret.ResourceVersion = "" // to force update
|
||||
delete(updateSecret.Data, "data-1")
|
||||
updateSecret.Data["data-3"] = []byte("value-3")
|
||||
_, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Update(updateSecret)
|
||||
Expect(err).NotTo(HaveOccurred(), "Failed to update secret %q in namespace %q", updateSecret.Name, f.Namespace.Name)
|
||||
|
||||
By(fmt.Sprintf("Creating secret with name %s", createSecret.Name))
|
||||
if createSecret, err = f.ClientSet.Core().Secrets(f.Namespace.Name).Create(createSecret); err != nil {
|
||||
framework.Failf("unable to create test secret %s: %v", createSecret.Name, err)
|
||||
}
|
||||
|
||||
By("waiting to observe update in volume")
|
||||
|
||||
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
||||
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-3"))
|
||||
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/secret-volumes/delete/data-1"))
|
||||
})
|
||||
|
||||
It("should be consumable from pods in env vars [Conformance]", func() {
|
||||
name := "secret-test-" + string(uuid.NewUUID())
|
||||
secret := secretForTest(f.Namespace.Name, name)
|
||||
|
Loading…
Reference in New Issue
Block a user