mirror of https://github.com/k3s-io/k3s
commit
3cfb090939
|
@ -2479,6 +2479,548 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/extensions/v1beta1/podsecuritypolicies",
|
||||
"description": "API at /apis/extensions/v1beta1",
|
||||
"operations": [
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicyList",
|
||||
"method": "GET",
|
||||
"summary": "list or watch objects of kind PodSecurityPolicy",
|
||||
"nickname": "listNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "labelSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "fieldSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "watch",
|
||||
"description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "resourceVersion",
|
||||
"description": "When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"paramType": "query",
|
||||
"name": "timeoutSeconds",
|
||||
"description": "Timeout for the list/watch call.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.PodSecurityPolicyList"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"method": "POST",
|
||||
"summary": "create a PodSecurityPolicy",
|
||||
"nickname": "createNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.PodSecurityPolicy"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "unversioned.Status",
|
||||
"method": "DELETE",
|
||||
"summary": "delete collection of PodSecurityPolicy",
|
||||
"nickname": "deletecollectionNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "labelSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "fieldSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "watch",
|
||||
"description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "resourceVersion",
|
||||
"description": "When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"paramType": "query",
|
||||
"name": "timeoutSeconds",
|
||||
"description": "Timeout for the list/watch call.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "unversioned.Status"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/extensions/v1beta1/watch/podsecuritypolicies",
|
||||
"description": "API at /apis/extensions/v1beta1",
|
||||
"operations": [
|
||||
{
|
||||
"type": "json.WatchEvent",
|
||||
"method": "GET",
|
||||
"summary": "watch individual changes to a list of PodSecurityPolicy",
|
||||
"nickname": "watchNamespacedPodSecurityPolicyList",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "labelSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "fieldSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "watch",
|
||||
"description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "resourceVersion",
|
||||
"description": "When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"paramType": "query",
|
||||
"name": "timeoutSeconds",
|
||||
"description": "Timeout for the list/watch call.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "json.WatchEvent"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/extensions/v1beta1/podsecuritypolicies/{name}",
|
||||
"description": "API at /apis/extensions/v1beta1",
|
||||
"operations": [
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"method": "GET",
|
||||
"summary": "read the specified PodSecurityPolicy",
|
||||
"nickname": "readNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "export",
|
||||
"description": "Should this value be exported. Export strips fields that a user can not specify.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "exact",
|
||||
"description": "Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the PodSecurityPolicy",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.PodSecurityPolicy"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"method": "PUT",
|
||||
"summary": "replace the specified PodSecurityPolicy",
|
||||
"nickname": "replaceNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the PodSecurityPolicy",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.PodSecurityPolicy"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.PodSecurityPolicy",
|
||||
"method": "PATCH",
|
||||
"summary": "partially update the specified PodSecurityPolicy",
|
||||
"nickname": "patchNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "unversioned.Patch",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the PodSecurityPolicy",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.PodSecurityPolicy"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/merge-patch+json",
|
||||
"application/strategic-merge-patch+json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "unversioned.Status",
|
||||
"method": "DELETE",
|
||||
"summary": "delete a PodSecurityPolicy",
|
||||
"nickname": "deleteNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1.DeleteOptions",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the PodSecurityPolicy",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "unversioned.Status"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/extensions/v1beta1/watch/podsecuritypolicies/{name}",
|
||||
"description": "API at /apis/extensions/v1beta1",
|
||||
"operations": [
|
||||
{
|
||||
"type": "json.WatchEvent",
|
||||
"method": "GET",
|
||||
"summary": "watch changes to an object of kind PodSecurityPolicy",
|
||||
"nickname": "watchNamespacedPodSecurityPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "labelSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "fieldSelector",
|
||||
"description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"paramType": "query",
|
||||
"name": "watch",
|
||||
"description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "resourceVersion",
|
||||
"description": "When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"paramType": "query",
|
||||
"name": "timeoutSeconds",
|
||||
"description": "Timeout for the list/watch call.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the PodSecurityPolicy",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "json.WatchEvent"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/extensions/v1beta1/namespaces/{namespace}/replicationcontrollers/{name}/scale",
|
||||
"description": "API at /apis/extensions/v1beta1",
|
||||
|
@ -4470,6 +5012,188 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.PodSecurityPolicyList": {
|
||||
"id": "v1beta1.PodSecurityPolicyList",
|
||||
"description": "Pod Security Policy List is a list of PodSecurityPolicy objects.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
|
||||
},
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "unversioned.ListMeta",
|
||||
"description": "Standard list metadata. More info: http://docs.k8s.io/api-conventions.md#metadata"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1beta1.PodSecurityPolicy"
|
||||
},
|
||||
"description": "Items is a list of schema objects."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.PodSecurityPolicy": {
|
||||
"id": "v1beta1.PodSecurityPolicy",
|
||||
"description": "Pod Security Policy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
|
||||
},
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "v1.ObjectMeta",
|
||||
"description": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"
|
||||
},
|
||||
"spec": {
|
||||
"$ref": "v1beta1.PodSecurityPolicySpec",
|
||||
"description": "Spec defines the policy enforced."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.PodSecurityPolicySpec": {
|
||||
"id": "v1beta1.PodSecurityPolicySpec",
|
||||
"description": "Pod Security Policy Spec defines the policy enforced.",
|
||||
"properties": {
|
||||
"privileged": {
|
||||
"type": "boolean",
|
||||
"description": "privileged determines if a pod can request to be run as privileged."
|
||||
},
|
||||
"capabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1.Capability"
|
||||
},
|
||||
"description": "capabilities is a list of capabilities that can be added."
|
||||
},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1beta1.FSType"
|
||||
},
|
||||
"description": "volumes is a white list of allowed volume plugins. Empty indicates that all plugins may be used."
|
||||
},
|
||||
"hostNetwork": {
|
||||
"type": "boolean",
|
||||
"description": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec."
|
||||
},
|
||||
"hostPorts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1beta1.HostPortRange"
|
||||
},
|
||||
"description": "hostPorts determines which host port ranges are allowed to be exposed."
|
||||
},
|
||||
"hostPID": {
|
||||
"type": "boolean",
|
||||
"description": "hostPID determines if the policy allows the use of HostPID in the pod spec."
|
||||
},
|
||||
"hostIPC": {
|
||||
"type": "boolean",
|
||||
"description": "hostIPC determines if the policy allows the use of HostIPC in the pod spec."
|
||||
},
|
||||
"seLinuxContext": {
|
||||
"$ref": "v1beta1.SELinuxContextStrategyOptions",
|
||||
"description": "seLinuxContext is the strategy that will dictate the allowable labels that may be set."
|
||||
},
|
||||
"runAsUser": {
|
||||
"$ref": "v1beta1.RunAsUserStrategyOptions",
|
||||
"description": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.FSType": {
|
||||
"id": "v1beta1.FSType",
|
||||
"properties": {}
|
||||
},
|
||||
"v1beta1.HostPortRange": {
|
||||
"id": "v1beta1.HostPortRange",
|
||||
"description": "Host Port Range defines a range of host ports that will be enabled by a policy for pods to use. It requires both the start and end to be defined.",
|
||||
"required": [
|
||||
"min",
|
||||
"max"
|
||||
],
|
||||
"properties": {
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "min is the start of the range, inclusive."
|
||||
},
|
||||
"max": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "max is the end of the range, inclusive."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.SELinuxContextStrategyOptions": {
|
||||
"id": "v1beta1.SELinuxContextStrategyOptions",
|
||||
"description": "SELinux Context Strategy Options defines the strategy type and any options used to create the strategy.",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "type is the strategy that will dictate the allowable labels that may be set."
|
||||
},
|
||||
"seLinuxOptions": {
|
||||
"$ref": "v1.SELinuxOptions",
|
||||
"description": "seLinuxOptions required to run as; required for MustRunAs More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.RunAsUserStrategyOptions": {
|
||||
"id": "v1beta1.RunAsUserStrategyOptions",
|
||||
"description": "Run A sUser Strategy Options defines the strategy type and any options used to create the strategy.",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "type is the strategy that will dictate the allowable RunAsUser values that may be set."
|
||||
},
|
||||
"ranges": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1beta1.IDRange"
|
||||
},
|
||||
"description": "Ranges are the allowed ranges of uids that may be used."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.IDRange": {
|
||||
"id": "v1beta1.IDRange",
|
||||
"description": "ID Range provides a min/max of an allowed range of IDs.",
|
||||
"required": [
|
||||
"min",
|
||||
"max"
|
||||
],
|
||||
"properties": {
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Min is the start of the range, inclusive."
|
||||
},
|
||||
"max": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "Max is the end of the range, inclusive."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta1.Scale": {
|
||||
"id": "v1beta1.Scale",
|
||||
"description": "represents a scaling request for a resource.",
|
||||
|
|
|
@ -330,6 +330,7 @@ _kubectl_get()
|
|||
must_have_one_noun+=("persistentvolume")
|
||||
must_have_one_noun+=("persistentvolumeclaim")
|
||||
must_have_one_noun+=("pod")
|
||||
must_have_one_noun+=("podsecuritypolicy")
|
||||
must_have_one_noun+=("podtemplate")
|
||||
must_have_one_noun+=("replicationcontroller")
|
||||
must_have_one_noun+=("resourcequota")
|
||||
|
@ -827,6 +828,7 @@ _kubectl_delete()
|
|||
must_have_one_noun+=("persistentvolume")
|
||||
must_have_one_noun+=("persistentvolumeclaim")
|
||||
must_have_one_noun+=("pod")
|
||||
must_have_one_noun+=("podsecuritypolicy")
|
||||
must_have_one_noun+=("podtemplate")
|
||||
must_have_one_noun+=("replicationcontroller")
|
||||
must_have_one_noun+=("resourcequota")
|
||||
|
@ -1964,6 +1966,7 @@ _kubectl_label()
|
|||
must_have_one_noun+=("persistentvolume")
|
||||
must_have_one_noun+=("persistentvolumeclaim")
|
||||
must_have_one_noun+=("pod")
|
||||
must_have_one_noun+=("podsecuritypolicy")
|
||||
must_have_one_noun+=("podtemplate")
|
||||
must_have_one_noun+=("replicationcontroller")
|
||||
must_have_one_noun+=("resourcequota")
|
||||
|
|
|
@ -458,6 +458,10 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_fstype">v1beta1.FSType</h3>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_selinuxoptions">v1.SELinuxOptions</h3>
|
||||
|
@ -595,6 +599,47 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_selinuxcontextstrategyoptions">v1beta1.SELinuxContextStrategyOptions</h3>
|
||||
<div class="paragraph">
|
||||
<p>SELinux Context Strategy Options defines the strategy type and any options used to create the strategy.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">type</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">type is the strategy that will dictate the allowable labels that may be set.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">seLinuxOptions</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">seLinuxOptions required to run as; required for MustRunAs More info: <a href="http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context">http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_selinuxoptions">v1.SELinuxOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_volumemount">v1.VolumeMount</h3>
|
||||
|
@ -1137,6 +1182,61 @@ Examples:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_podsecuritypolicylist">v1beta1.PodSecurityPolicyList</h3>
|
||||
<div class="paragraph">
|
||||
<p>Pod Security Policy List is a list of PodSecurityPolicy objects.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">kind</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: <a href="http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds">http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: <a href="http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources">http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">metadata</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Standard list metadata. More info: <a href="http://docs.k8s.io/api-conventions.md#metadata">http://docs.k8s.io/api-conventions.md#metadata</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_unversioned_listmeta">unversioned.ListMeta</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</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">Items is a list of schema objects.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1beta1_podsecuritypolicy">v1beta1.PodSecurityPolicy</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_tcpsocketaction">v1.TCPSocketAction</h3>
|
||||
|
@ -2706,6 +2806,47 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_hostportrange">v1beta1.HostPortRange</h3>
|
||||
<div class="paragraph">
|
||||
<p>Host Port Range defines a range of host ports that will be enabled by a policy for pods to use. It requires both the start and end to be defined.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">min</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">min is the start of the range, inclusive.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">max</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">max is the end of the range, inclusive.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_labelselectorrequirement">v1beta1.LabelSelectorRequirement</h3>
|
||||
|
@ -2816,6 +2957,47 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_runasuserstrategyoptions">v1beta1.RunAsUserStrategyOptions</h3>
|
||||
<div class="paragraph">
|
||||
<p>Run A sUser Strategy Options defines the strategy type and any options used to create the strategy.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">type</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">type is the strategy that will dictate the allowable RunAsUser values that may be set.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">ranges</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Ranges are the allowed ranges of uids that may be used.</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="#_v1beta1_idrange">v1beta1.IDRange</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_envvar">v1.EnvVar</h3>
|
||||
|
@ -3251,6 +3433,96 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_podsecuritypolicyspec">v1beta1.PodSecurityPolicySpec</h3>
|
||||
<div class="paragraph">
|
||||
<p>Pod Security Policy Spec defines the policy enforced.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">privileged</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">privileged determines if a pod can request to be run as privileged.</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>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">capabilities</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">capabilities is a list of capabilities that can be added.</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_capability">v1.Capability</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">volumes</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">volumes is a white list of allowed volume plugins. Empty indicates that all plugins may be used.</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="#_v1beta1_fstype">v1beta1.FSType</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostNetwork</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.</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>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostPorts</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostPorts determines which host port ranges are allowed to be exposed.</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="#_v1beta1_hostportrange">v1beta1.HostPortRange</a> array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostPID</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostPID determines if the policy allows the use of HostPID in the pod spec.</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>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostIPC</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">hostIPC determines if the policy allows the use of HostIPC in the pod spec.</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>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">seLinuxContext</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">seLinuxContext is the strategy that will dictate the allowable labels that may be set.</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="#_v1beta1_selinuxcontextstrategyoptions">v1beta1.SELinuxContextStrategyOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">runAsUser</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.</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="#_v1beta1_runasuserstrategyoptions">v1beta1.RunAsUserStrategyOptions</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_volume">v1.Volume</h3>
|
||||
|
@ -3594,6 +3866,61 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_podsecuritypolicy">v1beta1.PodSecurityPolicy</h3>
|
||||
<div class="paragraph">
|
||||
<p>Pod Security Policy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">kind</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: <a href="http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds">http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: <a href="http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources">http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">metadata</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Standard object’s metadata. More info: <a href="http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata">http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_objectmeta">v1.ObjectMeta</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">spec</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Spec defines the policy enforced.</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="#_v1beta1_podsecuritypolicyspec">v1beta1.PodSecurityPolicySpec</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1_capability">v1.Capability</h3>
|
||||
|
@ -3916,6 +4243,47 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_idrange">v1beta1.IDRange</h3>
|
||||
<div class="paragraph">
|
||||
<p>ID Range provides a min/max of an allowed range of IDs.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all" style="width:100%; ">
|
||||
<colgroup>
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
<col style="width:20%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Schema</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">min</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Min is the start of the range, inclusive.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">max</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Max is the end of the range, inclusive.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_v1beta1_horizontalpodautoscalerlist">v1beta1.HorizontalPodAutoscalerList</h3>
|
||||
|
@ -4464,7 +4832,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
|||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2016-02-01 21:08:12 UTC
|
||||
Last updated 2016-02-05 04:29:01 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,377 @@
|
|||
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
||||
|
||||
<!-- BEGIN STRIP_FOR_RELEASE -->
|
||||
|
||||
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
||||
width="25" height="25">
|
||||
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
||||
width="25" height="25">
|
||||
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
||||
width="25" height="25">
|
||||
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
||||
width="25" height="25">
|
||||
<img src="http://kubernetes.io/img/warning.png" alt="WARNING"
|
||||
width="25" height="25">
|
||||
|
||||
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
||||
|
||||
If you are using a released version of Kubernetes, you should
|
||||
refer to the docs that go with that version.
|
||||
|
||||
Documentation for other releases can be found at
|
||||
[releases.k8s.io](http://releases.k8s.io).
|
||||
</strong>
|
||||
--
|
||||
|
||||
<!-- END STRIP_FOR_RELEASE -->
|
||||
|
||||
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
||||
|
||||
## Abstract
|
||||
|
||||
PodSecurityPolicy allows cluster administrators to control the creation and validation of a security
|
||||
context for a pod and containers.
|
||||
|
||||
## Motivation
|
||||
|
||||
Administration of a multi-tenant cluster requires the ability to provide varying sets of permissions
|
||||
among the tenants, the infrastructure components, and end users of the system who may themselves be
|
||||
administrators within their own isolated namespace.
|
||||
|
||||
Actors in a cluster may include infrastructure that is managed by administrators, infrastructure
|
||||
that is exposed to end users (builds, deployments), the isolated end user namespaces in the cluster, and
|
||||
the individual users inside those namespaces. Infrastructure components that operate on behalf of a
|
||||
user (builds, deployments) should be allowed to run at an elevated level of permissions without
|
||||
granting the user themselves an elevated set of permissions.
|
||||
|
||||
## Goals
|
||||
|
||||
1. Associate [service accounts](http://docs.k8s.io/design/service_accounts.md), groups, and users with
|
||||
a set of constraints that dictate how a security context is established for a pod and the pod's containers.
|
||||
1. Provide the ability for users and infrastructure components to run pods with elevated privileges
|
||||
on behalf of another user or within a namespace where privileges are more restrictive.
|
||||
1. Secure the ability to reference elevated permissions or to change the constraints under which
|
||||
a user runs.
|
||||
|
||||
## Use Cases
|
||||
|
||||
Use case 1:
|
||||
As an administrator, I can create a namespace for a person that can't create privileged containers
|
||||
AND enforce that the UID of the containers is set to a certain value
|
||||
|
||||
Use case 2:
|
||||
As a cluster operator, an infrastructure component should be able to create a pod with elevated
|
||||
privileges in a namespace where regular users cannot create pods with these privileges or execute
|
||||
commands in that pod.
|
||||
|
||||
Use case 3:
|
||||
As a cluster administrator, I can allow a given namespace (or service account) to create privileged
|
||||
pods or to run root pods
|
||||
|
||||
Use case 4:
|
||||
As a cluster administrator, I can allow a project administrator to control the security contexts of
|
||||
pods and service accounts within a project
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
1. Provide a set of restrictions that controls how a security context is created for pods and containers
|
||||
as a new cluster-scoped object called `PodSecurityPolicy`.
|
||||
1. User information in `user.Info` must be available to admission controllers. (Completed in
|
||||
https://github.com/GoogleCloudPlatform/kubernetes/pull/8203)
|
||||
1. Some authorizers may restrict a user’s ability to reference a service account. Systems requiring
|
||||
the ability to secure service accounts on a user level must be able to add a policy that enables
|
||||
referencing specific service accounts themselves.
|
||||
1. Admission control must validate the creation of Pods against the allowed set of constraints.
|
||||
|
||||
## Design
|
||||
|
||||
### Model
|
||||
|
||||
PodSecurityPolicy objects exist in the root scope, outside of a namespace. The
|
||||
PodSecurityPolicy will reference users and groups that are allowed
|
||||
to operate under the constraints. In order to support this, `ServiceAccounts` must be mapped
|
||||
to a user name or group list by the authentication/authorization layers. This allows the security
|
||||
context to treat users, groups, and service accounts uniformly.
|
||||
|
||||
Below is a list of PodSecurityPolicies which will likely serve most use cases:
|
||||
|
||||
1. A default policy object. This object is permissioned to something which covers all actors, such
|
||||
as a `system:authenticated` group, and will likely be the most restrictive set of constraints.
|
||||
1. A default constraints object for service accounts. This object can be identified as serving
|
||||
a group identified by `system:service-accounts`, which can be imposed by the service account authenticator / token generator.
|
||||
1. Cluster admin constraints identified by `system:cluster-admins` group - a set of constraints with elevated privileges that can be used
|
||||
by an administrative user or group.
|
||||
1. Infrastructure components constraints which can be identified either by a specific service
|
||||
account or by a group containing all service accounts.
|
||||
|
||||
```go
|
||||
// PodSecurityPolicy governs the ability to make requests that affect the SecurityContext
|
||||
// that will be applied to a pod and container.
|
||||
type PodSecurityPolicy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the policy enforced.
|
||||
Spec PodSecurityPolicySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityPolicySpec defines the policy enforced.
|
||||
type PodSecurityPolicySpec struct {
|
||||
// Privileged determines if a pod can request to be run as privileged.
|
||||
Privileged bool `json:"privileged,omitempty"`
|
||||
// Capabilities is a list of capabilities that can be added.
|
||||
Capabilities []api.Capability `json:"capabilities,omitempty"`
|
||||
// Volumes allows and disallows the use of different types of volume plugins.
|
||||
Volumes VolumeSecurityPolicy `json:"volumes,omitempty"`
|
||||
// HostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
// HostPorts determines which host port ranges are allowed to be exposed.
|
||||
HostPorts []HostPortRange `json:"hostPorts,omitempty"`
|
||||
// HostPID determines if the policy allows the use of HostPID in the pod spec.
|
||||
HostPID bool `json:"hostPID,omitempty"`
|
||||
// HostIPC determines if the policy allows the use of HostIPC in the pod spec.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// SELinuxContext is the strategy that will dictate the allowable labels that may be set.
|
||||
SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty"`
|
||||
// RunAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty"`
|
||||
|
||||
// The users who have permissions to use this policy
|
||||
Users []string `json:"users,omitempty"`
|
||||
// The groups that have permission to use this policy
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
// HostPortRange defines a range of host ports that will be enabled by a policy
|
||||
// for pods to use. It requires both the start and end to be defined.
|
||||
type HostPortRange struct {
|
||||
// Start is the beginning of the port range which will be allowed.
|
||||
Start int `json:"start"`
|
||||
// End is the end of the port range which will be allowed.
|
||||
End int `json:"end"`
|
||||
}
|
||||
|
||||
// VolumeSecurityPolicy allows and disallows the use of different types of volume plugins.
|
||||
type VolumeSecurityPolicy struct {
|
||||
// HostPath allows or disallows the use of the HostPath volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath
|
||||
HostPath bool `json:"hostPath,omitempty"`
|
||||
// EmptyDir allows or disallows the use of the EmptyDir volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir
|
||||
EmptyDir bool `json:"emptyDir,omitempty"`
|
||||
// GCEPersistentDisk allows or disallows the use of the GCEPersistentDisk volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk
|
||||
GCEPersistentDisk bool `json:"gcePersistentDisk,omitempty"`
|
||||
// AWSElasticBlockStore allows or disallows the use of the AWSElasticBlockStore volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore
|
||||
AWSElasticBlockStore bool `json:"awsElasticBlockStore,omitempty"`
|
||||
// GitRepo allows or disallows the use of the GitRepo volume plugin.
|
||||
GitRepo bool `json:"gitRepo,omitempty"`
|
||||
// Secret allows or disallows the use of the Secret volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets
|
||||
Secret bool `json:"secret,omitempty"`
|
||||
// NFS allows or disallows the use of the NFS volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs
|
||||
NFS bool `json:"nfs,omitempty"`
|
||||
// ISCSI allows or disallows the use of the ISCSI volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/examples/iscsi/README.md
|
||||
ISCSI bool `json:"iscsi,omitempty"`
|
||||
// Glusterfs allows or disallows the use of the Glusterfs volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md
|
||||
Glusterfs bool `json:"glusterfs,omitempty"`
|
||||
// PersistentVolumeClaim allows or disallows the use of the PersistentVolumeClaim volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims
|
||||
PersistentVolumeClaim bool `json:"persistentVolumeClaim,omitempty"`
|
||||
// RBD allows or disallows the use of the RBD volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/examples/rbd/README.md
|
||||
RBD bool `json:"rbd,omitempty"`
|
||||
// Cinder allows or disallows the use of the Cinder volume plugin.
|
||||
// More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md
|
||||
Cinder bool `json:"cinder,omitempty"`
|
||||
// CephFS allows or disallows the use of the CephFS volume plugin.
|
||||
CephFS bool `json:"cephfs,omitempty"`
|
||||
// DownwardAPI allows or disallows the use of the DownwardAPI volume plugin.
|
||||
DownwardAPI bool `json:"downwardAPI,omitempty"`
|
||||
// FC allows or disallows the use of the FC volume plugin.
|
||||
FC bool `json:"fc,omitempty"`
|
||||
}
|
||||
|
||||
// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type SELinuxContextStrategyOptions struct {
|
||||
// Type is the strategy that will dictate the allowable labels that may be set.
|
||||
Type SELinuxContextStrategy `json:"type"`
|
||||
// seLinuxOptions required to run as; required for MustRunAs
|
||||
// More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context
|
||||
SELinuxOptions *api.SELinuxOptions `json:"seLinuxOptions,omitempty"`
|
||||
}
|
||||
|
||||
// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a
|
||||
// SecurityContext.
|
||||
type SELinuxContextStrategy string
|
||||
|
||||
const (
|
||||
// container must have SELinux labels of X applied.
|
||||
SELinuxStrategyMustRunAs SELinuxContextStrategy = "MustRunAs"
|
||||
// container may make requests for any SELinux context labels.
|
||||
SELinuxStrategyRunAsAny SELinuxContextStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type RunAsUserStrategyOptions struct {
|
||||
// Type is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
Type RunAsUserStrategy `json:"type"`
|
||||
// UID is the user id that containers must run as. Required for the MustRunAs strategy if not using
|
||||
// a strategy that supports pre-allocated uids.
|
||||
UID *int64 `json:"uid,omitempty"`
|
||||
// UIDRangeMin defines the min value for a strategy that allocates by a range based strategy.
|
||||
UIDRangeMin *int64 `json:"uidRangeMin,omitempty"`
|
||||
// UIDRangeMax defines the max value for a strategy that allocates by a range based strategy.
|
||||
UIDRangeMax *int64 `json:"uidRangeMax,omitempty"`
|
||||
}
|
||||
|
||||
// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a
|
||||
// SecurityContext.
|
||||
type RunAsUserStrategy string
|
||||
|
||||
const (
|
||||
// container must run as a particular uid.
|
||||
RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs"
|
||||
// container must run as a particular uid.
|
||||
RunAsUserStrategyMustRunAsRange RunAsUserStrategy = "MustRunAsRange"
|
||||
// container must run as a non-root uid
|
||||
RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot"
|
||||
// container may make requests for any uid.
|
||||
RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny"
|
||||
)
|
||||
```
|
||||
|
||||
### PodSecurityPolicy Lifecycle
|
||||
|
||||
As reusable objects in the root scope, PodSecurityPolicy follows the lifecycle of the
|
||||
cluster itself. Maintenance of constraints such as adding, assigning, or changing them is the
|
||||
responsibility of the cluster administrator.
|
||||
|
||||
Creating a new user within a namespace should not require the cluster administrator to
|
||||
define the user's PodSecurityPolicy. They should receive the default set of policies
|
||||
that the administrator has defined for the groups they are assigned.
|
||||
|
||||
|
||||
## Default PodSecurityPolicy And Overrides
|
||||
|
||||
In order to establish policy for service accounts and users, there must be a way
|
||||
to identify the default set of constraints that is to be used. This is best accomplished by using
|
||||
groups. As mentioned above, groups may be used by the authentication/authorization layer to ensure
|
||||
that every user maps to at least one group (with a default example of `system:authenticated`) and it
|
||||
is up to the cluster administrator to ensure that a `PodSecurityPolicy` object exists that
|
||||
references the group.
|
||||
|
||||
If an administrator would like to provide a user with a changed set of security context permissions,
|
||||
they may do the following:
|
||||
|
||||
1. Create a new `PodSecurityPolicy` object and add a reference to the user or a group
|
||||
that the user belongs to.
|
||||
1. Add the user (or group) to an existing `PodSecurityPolicy` object with the proper
|
||||
elevated privileges.
|
||||
|
||||
## Admission
|
||||
|
||||
Admission control using an authorizer provides the ability to control the creation of resources
|
||||
based on capabilities granted to a user. In terms of the `PodSecurityPolicy`, it means
|
||||
that an admission controller may inspect the user info made available in the context to retrieve
|
||||
an appropriate set of policies for validation.
|
||||
|
||||
The appropriate set of PodSecurityPolicies is defined as all of the policies
|
||||
available that have reference to the user or groups that the user belongs to.
|
||||
|
||||
Admission will use the PodSecurityPolicy to ensure that any requests for a
|
||||
specific security context setting are valid and to generate settings using the following approach:
|
||||
|
||||
1. Determine all the available `PodSecurityPolicy` objects that are allowed to be used
|
||||
1. Sort the `PodSecurityPolicy` objects in a most restrictive to least restrictive order.
|
||||
1. For each `PodSecurityPolicy`, generate a `SecurityContext` for each container. The generation phase will not override
|
||||
any user requested settings in the `SecurityContext`, and will rely on the validation phase to ensure that
|
||||
the user requests are valid.
|
||||
1. Validate the generated `SecurityContext` to ensure it falls within the boundaries of the `PodSecurityPolicy`
|
||||
1. If all containers validate under a single `PodSecurityPolicy` then the pod will be admitted
|
||||
1. If all containers DO NOT validate under the `PodSecurityPolicy` then try the next `PodSecurityPolicy`
|
||||
1. If no `PodSecurityPolicy` validates for the pod then the pod will not be admitted
|
||||
|
||||
|
||||
## Creation of a SecurityContext Based on PodSecurityPolicy
|
||||
|
||||
The creation of a `SecurityContext` based on a `PodSecurityPolicy` is based upon the configured
|
||||
settings of the `PodSecurityPolicy`.
|
||||
|
||||
There are three scenarios under which a `PodSecurityPolicy` field may fall:
|
||||
|
||||
1. Governed by a boolean: fields of this type will be defaulted to the most restrictive value.
|
||||
For instance, `AllowPrivileged` will always be set to false if unspecified.
|
||||
|
||||
1. Governed by an allowable set: fields of this type will be checked against the set to ensure
|
||||
their value is allowed. For example, `AllowCapabilities` will ensure that only capabilities
|
||||
that are allowed to be requested are considered valid. `HostNetworkSources` will ensure that
|
||||
only pods created from source X are allowed to request access to the host network.
|
||||
1. Governed by a strategy: Items that have a strategy to generate a value will provide a
|
||||
mechanism to generate the value as well as a mechanism to ensure that a specified value falls into
|
||||
the set of allowable values. See the Types section for the description of the interfaces that
|
||||
strategies must implement.
|
||||
|
||||
Strategies have the ability to become dynamic. In order to support a dynamic strategy it should be
|
||||
possible to make a strategy that has the ability to either be pre-populated with dynamic data by
|
||||
another component (such as an admission controller) or has the ability to retrieve the information
|
||||
itself based on the data in the pod. An example of this would be a pre-allocated UID for the namespace.
|
||||
A dynamic `RunAsUser` strategy could inspect the namespace of the pod in order to find the required pre-allocated
|
||||
UID and generate or validate requests based on that information.
|
||||
|
||||
|
||||
```go
|
||||
// SELinuxStrategy defines the interface for all SELinux constraint strategies.
|
||||
type SELinuxStrategy interface {
|
||||
// Generate creates the SELinuxOptions based on constraint rules.
|
||||
Generate(pod *api.Pod, container *api.Container) (*api.SELinuxOptions, error)
|
||||
// Validate ensures that the specified values fall within the range of the strategy.
|
||||
Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList
|
||||
}
|
||||
|
||||
// RunAsUserStrategy defines the interface for all uid constraint strategies.
|
||||
type RunAsUserStrategy interface {
|
||||
// Generate creates the uid based on policy rules.
|
||||
Generate(pod *api.Pod, container *api.Container) (*int64, error)
|
||||
// Validate ensures that the specified values fall within the range of the strategy.
|
||||
Validate(pod *api.Pod, container *api.Container) fielderrors.ValidationErrorList
|
||||
}
|
||||
```
|
||||
|
||||
## Escalating Privileges by an Administrator
|
||||
|
||||
An administrator may wish to create a resource in a namespace that runs with
|
||||
escalated privileges. By allowing security context
|
||||
constraints to operate on both the requesting user and the pod's service account, administrators are able to
|
||||
create pods in namespaces with elevated privileges based on the administrator's security context
|
||||
constraints.
|
||||
|
||||
This also allows the system to guard commands being executed in the non-conforming container. For
|
||||
instance, an `exec` command can first check the security context of the pod against the security
|
||||
context constraints of the user or the user's ability to reference a service account.
|
||||
If it does not validate then it can block users from executing the command. Since the validation
|
||||
will be user aware, administrators would still be able to run the commands that are restricted to normal users.
|
||||
|
||||
## Interaction with the Kubelet
|
||||
|
||||
In certain cases, the Kubelet may need provide information about
|
||||
the image in order to validate the security context. An example of this is a cluster
|
||||
that is configured to run with a UID strategy of `MustRunAsNonRoot`.
|
||||
|
||||
In this case the admission controller can set the existing `MustRunAsNonRoot` flag on the `SecurityContext`
|
||||
based on the UID strategy of the `SecurityPolicy`. It should still validate any requests on the pod
|
||||
for a specific UID and fail early if possible. However, if the `RunAsUser` is not set on the pod
|
||||
it should still admit the pod and allow the Kubelet to ensure that the image does not run as
|
||||
`root` with the existing non-root checks.
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/proposals/security-context-constraints.md?pixel)]()
|
||||
<!-- END MUNGE: GENERATED_ANALYTICS -->
|
|
@ -404,6 +404,13 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
|
|||
MaxUnavailable: intstr.FromInt(10),
|
||||
}
|
||||
},
|
||||
func(psp *extensions.PodSecurityPolicySpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(psp) // fuzz self without calling this function again
|
||||
userTypes := []extensions.RunAsUserStrategy{extensions.RunAsUserStrategyMustRunAsNonRoot, extensions.RunAsUserStrategyMustRunAs, extensions.RunAsUserStrategyRunAsAny}
|
||||
psp.RunAsUser.Type = userTypes[c.Rand.Intn(len(userTypes))]
|
||||
seLinuxTypes := []extensions.SELinuxContextStrategy{extensions.SELinuxStrategyRunAsAny, extensions.SELinuxStrategyMustRunAs}
|
||||
psp.SELinuxContext.Type = seLinuxTypes[c.Rand.Intn(len(seLinuxTypes))]
|
||||
},
|
||||
)
|
||||
return f
|
||||
}
|
||||
|
|
|
@ -90,7 +90,9 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
|
|||
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper {
|
||||
// the list of kinds that are scoped at the root of the api hierarchy
|
||||
// if a kind is not enumerated here, it is assumed to have a namespace scope
|
||||
rootScoped := sets.NewString()
|
||||
rootScoped := sets.NewString(
|
||||
"PodSecurityPolicy",
|
||||
)
|
||||
|
||||
ignoredKinds := sets.NewString()
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ func addKnownTypes(scheme *runtime.Scheme) {
|
|||
&ReplicaSet{},
|
||||
&ReplicaSetList{},
|
||||
&api.ExportOptions{},
|
||||
&PodSecurityPolicy{},
|
||||
&PodSecurityPolicyList{},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -94,3 +96,5 @@ func (obj *Ingress) GetObjectKind() unversioned.ObjectKind {
|
|||
func (obj *IngressList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ReplicaSet) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ReplicaSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *PodSecurityPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *PodSecurityPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -842,3 +842,123 @@ type ReplicaSetStatus struct {
|
|||
// ObservedGeneration is the most recent generation observed by the controller.
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityPolicy governs the ability to make requests that affect the SecurityContext
|
||||
// that will be applied to a pod and container.
|
||||
type PodSecurityPolicy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the policy enforced.
|
||||
Spec PodSecurityPolicySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityPolicySpec defines the policy enforced.
|
||||
type PodSecurityPolicySpec struct {
|
||||
// Privileged determines if a pod can request to be run as privileged.
|
||||
Privileged bool `json:"privileged,omitempty"`
|
||||
// Capabilities is a list of capabilities that can be added.
|
||||
Capabilities []api.Capability `json:"capabilities,omitempty"`
|
||||
// Volumes is a white list of allowed volume plugins. Empty indicates that all plugins
|
||||
// may be used.
|
||||
Volumes []FSType `json:"volumes,omitempty"`
|
||||
// HostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
// HostPorts determines which host port ranges are allowed to be exposed.
|
||||
HostPorts []HostPortRange `json:"hostPorts,omitempty"`
|
||||
// HostPID determines if the policy allows the use of HostPID in the pod spec.
|
||||
HostPID bool `json:"hostPID,omitempty"`
|
||||
// HostIPC determines if the policy allows the use of HostIPC in the pod spec.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// SELinuxContext is the strategy that will dictate the allowable labels that may be set.
|
||||
SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty"`
|
||||
// RunAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty"`
|
||||
}
|
||||
|
||||
// HostPortRange defines a range of host ports that will be enabled by a policy
|
||||
// for pods to use. It requires both the start and end to be defined.
|
||||
type HostPortRange struct {
|
||||
// Min is the start of the range, inclusive.
|
||||
Min int `json:"min"`
|
||||
// Max is the end of the range, inclusive.
|
||||
Max int `json:"max"`
|
||||
}
|
||||
|
||||
// FSType gives strong typing to different file systems that are used by volumes.
|
||||
type FSType string
|
||||
|
||||
var (
|
||||
HostPath FSType = "hostPath"
|
||||
EmptyDir FSType = "emptyDir"
|
||||
GCEPersistentDisk FSType = "gcePersistentDisk"
|
||||
AWSElasticBlockStore FSType = "awsElasticBlockStore"
|
||||
GitRepo FSType = "gitRepo"
|
||||
Secret FSType = "secret"
|
||||
NFS FSType = "nfs"
|
||||
ISCSI FSType = "iscsi"
|
||||
Glusterfs FSType = "glusterfs"
|
||||
PersistentVolumeClaim FSType = "persistentVolumeClaim"
|
||||
RBD FSType = "rbd"
|
||||
Cinder FSType = "cinder"
|
||||
CephFS FSType = "cephFS"
|
||||
DownwardAPI FSType = "downwardAPI"
|
||||
FC FSType = "fc"
|
||||
)
|
||||
|
||||
// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type SELinuxContextStrategyOptions struct {
|
||||
// Type is the strategy that will dictate the allowable labels that may be set.
|
||||
Type SELinuxContextStrategy `json:"type"`
|
||||
// seLinuxOptions required to run as; required for MustRunAs
|
||||
// More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context
|
||||
SELinuxOptions *api.SELinuxOptions `json:"seLinuxOptions,omitempty"`
|
||||
}
|
||||
|
||||
// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a
|
||||
// SecurityContext.
|
||||
type SELinuxContextStrategy string
|
||||
|
||||
const (
|
||||
// container must have SELinux labels of X applied.
|
||||
SELinuxStrategyMustRunAs SELinuxContextStrategy = "MustRunAs"
|
||||
// container may make requests for any SELinux context labels.
|
||||
SELinuxStrategyRunAsAny SELinuxContextStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type RunAsUserStrategyOptions struct {
|
||||
// Type is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
Type RunAsUserStrategy `json:"type"`
|
||||
// Ranges are the allowed ranges of uids that may be used.
|
||||
Ranges []IDRange `json:"ranges,omitempty"`
|
||||
}
|
||||
|
||||
// IDRange provides a min/max of an allowed range of IDs.
|
||||
type IDRange struct {
|
||||
// Min is the start of the range, inclusive.
|
||||
Min int64 `json:"min"`
|
||||
// Max is the end of the range, inclusive.
|
||||
Max int64 `json:"max"`
|
||||
}
|
||||
|
||||
// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a
|
||||
// SecurityContext.
|
||||
type RunAsUserStrategy string
|
||||
|
||||
const (
|
||||
// container must run as a particular uid.
|
||||
RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs"
|
||||
// container must run as a non-root uid
|
||||
RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot"
|
||||
// container may make requests for any uid.
|
||||
RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// PodSecurityPolicyList is a list of PodSecurityPolicy objects.
|
||||
type PodSecurityPolicyList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []PodSecurityPolicy `json:"items"`
|
||||
}
|
||||
|
|
|
@ -2982,6 +2982,32 @@ func Convert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAu
|
|||
return autoConvert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_HostPortRange_To_v1beta1_HostPortRange(in *extensions.HostPortRange, out *HostPortRange, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.HostPortRange))(in)
|
||||
}
|
||||
out.Min = int32(in.Min)
|
||||
out.Max = int32(in.Max)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_HostPortRange_To_v1beta1_HostPortRange(in *extensions.HostPortRange, out *HostPortRange, s conversion.Scope) error {
|
||||
return autoConvert_extensions_HostPortRange_To_v1beta1_HostPortRange(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_IDRange_To_v1beta1_IDRange(in *extensions.IDRange, out *IDRange, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.IDRange))(in)
|
||||
}
|
||||
out.Min = in.Min
|
||||
out.Max = in.Max
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_IDRange_To_v1beta1_IDRange(in *extensions.IDRange, out *IDRange, s conversion.Scope) error {
|
||||
return autoConvert_extensions_IDRange_To_v1beta1_IDRange(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_Ingress_To_v1beta1_Ingress(in *extensions.Ingress, out *Ingress, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.Ingress))(in)
|
||||
|
@ -3293,6 +3319,100 @@ func Convert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(in *extension
|
|||
return autoConvert_extensions_NodeUtilization_To_v1beta1_NodeUtilization(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy(in *extensions.PodSecurityPolicy, out *PodSecurityPolicy, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.PodSecurityPolicy))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy(in *extensions.PodSecurityPolicy, out *PodSecurityPolicy, s conversion.Scope) error {
|
||||
return autoConvert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_PodSecurityPolicyList_To_v1beta1_PodSecurityPolicyList(in *extensions.PodSecurityPolicyList, out *PodSecurityPolicyList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.PodSecurityPolicyList))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]PodSecurityPolicy, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := Convert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_PodSecurityPolicyList_To_v1beta1_PodSecurityPolicyList(in *extensions.PodSecurityPolicyList, out *PodSecurityPolicyList, s conversion.Scope) error {
|
||||
return autoConvert_extensions_PodSecurityPolicyList_To_v1beta1_PodSecurityPolicyList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(in *extensions.PodSecurityPolicySpec, out *PodSecurityPolicySpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.PodSecurityPolicySpec))(in)
|
||||
}
|
||||
out.Privileged = in.Privileged
|
||||
if in.Capabilities != nil {
|
||||
out.Capabilities = make([]v1.Capability, len(in.Capabilities))
|
||||
for i := range in.Capabilities {
|
||||
out.Capabilities[i] = v1.Capability(in.Capabilities[i])
|
||||
}
|
||||
} else {
|
||||
out.Capabilities = nil
|
||||
}
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]FSType, len(in.Volumes))
|
||||
for i := range in.Volumes {
|
||||
out.Volumes[i] = FSType(in.Volumes[i])
|
||||
}
|
||||
} else {
|
||||
out.Volumes = nil
|
||||
}
|
||||
out.HostNetwork = in.HostNetwork
|
||||
if in.HostPorts != nil {
|
||||
out.HostPorts = make([]HostPortRange, len(in.HostPorts))
|
||||
for i := range in.HostPorts {
|
||||
if err := Convert_extensions_HostPortRange_To_v1beta1_HostPortRange(&in.HostPorts[i], &out.HostPorts[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HostPorts = nil
|
||||
}
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if err := Convert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(in *extensions.PodSecurityPolicySpec, out *PodSecurityPolicySpec, s conversion.Scope) error {
|
||||
return autoConvert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_ReplicaSet_To_v1beta1_ReplicaSet(in *extensions.ReplicaSet, out *ReplicaSet, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.ReplicaSet))(in)
|
||||
|
@ -3434,6 +3554,49 @@ func autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDepl
|
|||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(in *extensions.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.RunAsUserStrategyOptions))(in)
|
||||
}
|
||||
out.Type = RunAsUserStrategy(in.Type)
|
||||
if in.Ranges != nil {
|
||||
out.Ranges = make([]IDRange, len(in.Ranges))
|
||||
for i := range in.Ranges {
|
||||
if err := Convert_extensions_IDRange_To_v1beta1_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Ranges = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(in *extensions.RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, s conversion.Scope) error {
|
||||
return autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in *extensions.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.SELinuxContextStrategyOptions))(in)
|
||||
}
|
||||
out.Type = SELinuxContextStrategy(in.Type)
|
||||
// unable to generate simple pointer conversion for api.SELinuxOptions -> v1.SELinuxOptions
|
||||
if in.SELinuxOptions != nil {
|
||||
out.SELinuxOptions = new(v1.SELinuxOptions)
|
||||
if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SELinuxOptions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in *extensions.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error {
|
||||
return autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_extensions_Scale_To_v1beta1_Scale(in *extensions.Scale, out *Scale, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.Scale))(in)
|
||||
|
@ -4090,6 +4253,32 @@ func Convert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAu
|
|||
return autoConvert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_HostPortRange_To_extensions_HostPortRange(in *HostPortRange, out *extensions.HostPortRange, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*HostPortRange))(in)
|
||||
}
|
||||
out.Min = int(in.Min)
|
||||
out.Max = int(in.Max)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_HostPortRange_To_extensions_HostPortRange(in *HostPortRange, out *extensions.HostPortRange, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_HostPortRange_To_extensions_HostPortRange(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_IDRange_To_extensions_IDRange(in *IDRange, out *extensions.IDRange, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*IDRange))(in)
|
||||
}
|
||||
out.Min = in.Min
|
||||
out.Max = in.Max
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_IDRange_To_extensions_IDRange(in *IDRange, out *extensions.IDRange, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_IDRange_To_extensions_IDRange(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Ingress_To_extensions_Ingress(in *Ingress, out *extensions.Ingress, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Ingress))(in)
|
||||
|
@ -4479,6 +4668,100 @@ func Convert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(in *NodeUtili
|
|||
return autoConvert_v1beta1_NodeUtilization_To_extensions_NodeUtilization(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy(in *PodSecurityPolicy, out *extensions.PodSecurityPolicy, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*PodSecurityPolicy))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy(in *PodSecurityPolicy, out *extensions.PodSecurityPolicy, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PodSecurityPolicyList_To_extensions_PodSecurityPolicyList(in *PodSecurityPolicyList, out *extensions.PodSecurityPolicyList, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*PodSecurityPolicyList))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]extensions.PodSecurityPolicy, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := Convert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy(&in.Items[i], &out.Items[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_PodSecurityPolicyList_To_extensions_PodSecurityPolicyList(in *PodSecurityPolicyList, out *extensions.PodSecurityPolicyList, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PodSecurityPolicyList_To_extensions_PodSecurityPolicyList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySpec(in *PodSecurityPolicySpec, out *extensions.PodSecurityPolicySpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*PodSecurityPolicySpec))(in)
|
||||
}
|
||||
out.Privileged = in.Privileged
|
||||
if in.Capabilities != nil {
|
||||
out.Capabilities = make([]api.Capability, len(in.Capabilities))
|
||||
for i := range in.Capabilities {
|
||||
out.Capabilities[i] = api.Capability(in.Capabilities[i])
|
||||
}
|
||||
} else {
|
||||
out.Capabilities = nil
|
||||
}
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]extensions.FSType, len(in.Volumes))
|
||||
for i := range in.Volumes {
|
||||
out.Volumes[i] = extensions.FSType(in.Volumes[i])
|
||||
}
|
||||
} else {
|
||||
out.Volumes = nil
|
||||
}
|
||||
out.HostNetwork = in.HostNetwork
|
||||
if in.HostPorts != nil {
|
||||
out.HostPorts = make([]extensions.HostPortRange, len(in.HostPorts))
|
||||
for i := range in.HostPorts {
|
||||
if err := Convert_v1beta1_HostPortRange_To_extensions_HostPortRange(&in.HostPorts[i], &out.HostPorts[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HostPorts = nil
|
||||
}
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if err := Convert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySpec(in *PodSecurityPolicySpec, out *extensions.PodSecurityPolicySpec, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ReplicaSet_To_extensions_ReplicaSet(in *ReplicaSet, out *extensions.ReplicaSet, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*ReplicaSet))(in)
|
||||
|
@ -4612,6 +4895,49 @@ func autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDepl
|
|||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *extensions.RunAsUserStrategyOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*RunAsUserStrategyOptions))(in)
|
||||
}
|
||||
out.Type = extensions.RunAsUserStrategy(in.Type)
|
||||
if in.Ranges != nil {
|
||||
out.Ranges = make([]extensions.IDRange, len(in.Ranges))
|
||||
for i := range in.Ranges {
|
||||
if err := Convert_v1beta1_IDRange_To_extensions_IDRange(&in.Ranges[i], &out.Ranges[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Ranges = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(in *RunAsUserStrategyOptions, out *extensions.RunAsUserStrategyOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *extensions.SELinuxContextStrategyOptions, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*SELinuxContextStrategyOptions))(in)
|
||||
}
|
||||
out.Type = extensions.SELinuxContextStrategy(in.Type)
|
||||
// unable to generate simple pointer conversion for v1.SELinuxOptions -> api.SELinuxOptions
|
||||
if in.SELinuxOptions != nil {
|
||||
out.SELinuxOptions = new(api.SELinuxOptions)
|
||||
if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SELinuxOptions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *extensions.SELinuxContextStrategyOptions, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Scale_To_extensions_Scale(in *Scale, out *extensions.Scale, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*Scale))(in)
|
||||
|
@ -4853,6 +5179,8 @@ func init() {
|
|||
autoConvert_extensions_HorizontalPodAutoscalerSpec_To_v1beta1_HorizontalPodAutoscalerSpec,
|
||||
autoConvert_extensions_HorizontalPodAutoscalerStatus_To_v1beta1_HorizontalPodAutoscalerStatus,
|
||||
autoConvert_extensions_HorizontalPodAutoscaler_To_v1beta1_HorizontalPodAutoscaler,
|
||||
autoConvert_extensions_HostPortRange_To_v1beta1_HostPortRange,
|
||||
autoConvert_extensions_IDRange_To_v1beta1_IDRange,
|
||||
autoConvert_extensions_IngressBackend_To_v1beta1_IngressBackend,
|
||||
autoConvert_extensions_IngressList_To_v1beta1_IngressList,
|
||||
autoConvert_extensions_IngressRuleValue_To_v1beta1_IngressRuleValue,
|
||||
|
@ -4866,6 +5194,9 @@ func init() {
|
|||
autoConvert_extensions_JobStatus_To_v1beta1_JobStatus,
|
||||
autoConvert_extensions_Job_To_v1beta1_Job,
|
||||
autoConvert_extensions_NodeUtilization_To_v1beta1_NodeUtilization,
|
||||
autoConvert_extensions_PodSecurityPolicyList_To_v1beta1_PodSecurityPolicyList,
|
||||
autoConvert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySpec,
|
||||
autoConvert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy,
|
||||
autoConvert_extensions_ReplicaSetList_To_v1beta1_ReplicaSetList,
|
||||
autoConvert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec,
|
||||
autoConvert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus,
|
||||
|
@ -4874,6 +5205,8 @@ func init() {
|
|||
autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig,
|
||||
autoConvert_extensions_RollingUpdateDaemonSet_To_v1beta1_RollingUpdateDaemonSet,
|
||||
autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment,
|
||||
autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions,
|
||||
autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions,
|
||||
autoConvert_extensions_ScaleSpec_To_v1beta1_ScaleSpec,
|
||||
autoConvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus,
|
||||
autoConvert_extensions_Scale_To_v1beta1_Scale,
|
||||
|
@ -4949,6 +5282,8 @@ func init() {
|
|||
autoConvert_v1beta1_HorizontalPodAutoscalerSpec_To_extensions_HorizontalPodAutoscalerSpec,
|
||||
autoConvert_v1beta1_HorizontalPodAutoscalerStatus_To_extensions_HorizontalPodAutoscalerStatus,
|
||||
autoConvert_v1beta1_HorizontalPodAutoscaler_To_extensions_HorizontalPodAutoscaler,
|
||||
autoConvert_v1beta1_HostPortRange_To_extensions_HostPortRange,
|
||||
autoConvert_v1beta1_IDRange_To_extensions_IDRange,
|
||||
autoConvert_v1beta1_IngressBackend_To_extensions_IngressBackend,
|
||||
autoConvert_v1beta1_IngressList_To_extensions_IngressList,
|
||||
autoConvert_v1beta1_IngressRuleValue_To_extensions_IngressRuleValue,
|
||||
|
@ -4965,6 +5300,9 @@ func init() {
|
|||
autoConvert_v1beta1_LabelSelector_To_unversioned_LabelSelector,
|
||||
autoConvert_v1beta1_ListOptions_To_api_ListOptions,
|
||||
autoConvert_v1beta1_NodeUtilization_To_extensions_NodeUtilization,
|
||||
autoConvert_v1beta1_PodSecurityPolicyList_To_extensions_PodSecurityPolicyList,
|
||||
autoConvert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySpec,
|
||||
autoConvert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy,
|
||||
autoConvert_v1beta1_ReplicaSetList_To_extensions_ReplicaSetList,
|
||||
autoConvert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec,
|
||||
autoConvert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus,
|
||||
|
@ -4973,6 +5311,8 @@ func init() {
|
|||
autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig,
|
||||
autoConvert_v1beta1_RollingUpdateDaemonSet_To_extensions_RollingUpdateDaemonSet,
|
||||
autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment,
|
||||
autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions,
|
||||
autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions,
|
||||
autoConvert_v1beta1_ScaleSpec_To_extensions_ScaleSpec,
|
||||
autoConvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus,
|
||||
autoConvert_v1beta1_Scale_To_extensions_Scale,
|
||||
|
|
|
@ -1319,6 +1319,18 @@ func deepCopy_v1beta1_HorizontalPodAutoscalerStatus(in HorizontalPodAutoscalerSt
|
|||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_HostPortRange(in HostPortRange, out *HostPortRange, c *conversion.Cloner) error {
|
||||
out.Min = in.Min
|
||||
out.Max = in.Max
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_IDRange(in IDRange, out *IDRange, c *conversion.Cloner) error {
|
||||
out.Min = in.Min
|
||||
out.Max = in.Max
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_Ingress(in Ingress, out *Ingress, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
|
@ -1587,6 +1599,79 @@ func deepCopy_v1beta1_NodeUtilization(in NodeUtilization, out *NodeUtilization,
|
|||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_PodSecurityPolicy(in PodSecurityPolicy, out *PodSecurityPolicy, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1beta1_PodSecurityPolicySpec(in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_PodSecurityPolicyList(in PodSecurityPolicyList, out *PodSecurityPolicyList, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if in.Items != nil {
|
||||
out.Items = make([]PodSecurityPolicy, len(in.Items))
|
||||
for i := range in.Items {
|
||||
if err := deepCopy_v1beta1_PodSecurityPolicy(in.Items[i], &out.Items[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_PodSecurityPolicySpec(in PodSecurityPolicySpec, out *PodSecurityPolicySpec, c *conversion.Cloner) error {
|
||||
out.Privileged = in.Privileged
|
||||
if in.Capabilities != nil {
|
||||
out.Capabilities = make([]v1.Capability, len(in.Capabilities))
|
||||
for i := range in.Capabilities {
|
||||
out.Capabilities[i] = in.Capabilities[i]
|
||||
}
|
||||
} else {
|
||||
out.Capabilities = nil
|
||||
}
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]FSType, len(in.Volumes))
|
||||
for i := range in.Volumes {
|
||||
out.Volumes[i] = in.Volumes[i]
|
||||
}
|
||||
} else {
|
||||
out.Volumes = nil
|
||||
}
|
||||
out.HostNetwork = in.HostNetwork
|
||||
if in.HostPorts != nil {
|
||||
out.HostPorts = make([]HostPortRange, len(in.HostPorts))
|
||||
for i := range in.HostPorts {
|
||||
if err := deepCopy_v1beta1_HostPortRange(in.HostPorts[i], &out.HostPorts[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.HostPorts = nil
|
||||
}
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if err := deepCopy_v1beta1_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := deepCopy_v1beta1_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_ReplicaSet(in ReplicaSet, out *ReplicaSet, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
|
@ -1700,6 +1785,34 @@ func deepCopy_v1beta1_RollingUpdateDeployment(in RollingUpdateDeployment, out *R
|
|||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error {
|
||||
out.Type = in.Type
|
||||
if in.Ranges != nil {
|
||||
out.Ranges = make([]IDRange, len(in.Ranges))
|
||||
for i := range in.Ranges {
|
||||
if err := deepCopy_v1beta1_IDRange(in.Ranges[i], &out.Ranges[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Ranges = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error {
|
||||
out.Type = in.Type
|
||||
if in.SELinuxOptions != nil {
|
||||
out.SELinuxOptions = new(v1.SELinuxOptions)
|
||||
if err := deepCopy_v1_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SELinuxOptions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1beta1_Scale(in Scale, out *Scale, c *conversion.Cloner) error {
|
||||
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
|
||||
return err
|
||||
|
@ -1901,6 +2014,8 @@ func init() {
|
|||
deepCopy_v1beta1_HorizontalPodAutoscalerList,
|
||||
deepCopy_v1beta1_HorizontalPodAutoscalerSpec,
|
||||
deepCopy_v1beta1_HorizontalPodAutoscalerStatus,
|
||||
deepCopy_v1beta1_HostPortRange,
|
||||
deepCopy_v1beta1_IDRange,
|
||||
deepCopy_v1beta1_Ingress,
|
||||
deepCopy_v1beta1_IngressBackend,
|
||||
deepCopy_v1beta1_IngressList,
|
||||
|
@ -1917,6 +2032,9 @@ func init() {
|
|||
deepCopy_v1beta1_LabelSelectorRequirement,
|
||||
deepCopy_v1beta1_ListOptions,
|
||||
deepCopy_v1beta1_NodeUtilization,
|
||||
deepCopy_v1beta1_PodSecurityPolicy,
|
||||
deepCopy_v1beta1_PodSecurityPolicyList,
|
||||
deepCopy_v1beta1_PodSecurityPolicySpec,
|
||||
deepCopy_v1beta1_ReplicaSet,
|
||||
deepCopy_v1beta1_ReplicaSetList,
|
||||
deepCopy_v1beta1_ReplicaSetSpec,
|
||||
|
@ -1925,6 +2043,8 @@ func init() {
|
|||
deepCopy_v1beta1_RollbackConfig,
|
||||
deepCopy_v1beta1_RollingUpdateDaemonSet,
|
||||
deepCopy_v1beta1_RollingUpdateDeployment,
|
||||
deepCopy_v1beta1_RunAsUserStrategyOptions,
|
||||
deepCopy_v1beta1_SELinuxContextStrategyOptions,
|
||||
deepCopy_v1beta1_Scale,
|
||||
deepCopy_v1beta1_ScaleSpec,
|
||||
deepCopy_v1beta1_ScaleStatus,
|
||||
|
|
|
@ -60,6 +60,8 @@ func addKnownTypes(scheme *runtime.Scheme) {
|
|||
&v1.DeleteOptions{},
|
||||
&ReplicaSet{},
|
||||
&ReplicaSetList{},
|
||||
&PodSecurityPolicy{},
|
||||
&PodSecurityPolicyList{},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -85,3 +87,5 @@ func (obj *IngressList) GetObjectKind() unversioned.ObjectKind {
|
|||
func (obj *ListOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ReplicaSet) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *ReplicaSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *PodSecurityPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
func (obj *PodSecurityPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -917,3 +917,128 @@ type ReplicaSetStatus struct {
|
|||
// ObservedGeneration reflects the generation of the most recently observed ReplicaSet.
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
}
|
||||
|
||||
// Pod Security Policy governs the ability to make requests that affect the Security Context
|
||||
// that will be applied to a pod and container.
|
||||
type PodSecurityPolicy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
v1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the policy enforced.
|
||||
Spec PodSecurityPolicySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// Pod Security Policy Spec defines the policy enforced.
|
||||
type PodSecurityPolicySpec struct {
|
||||
// privileged determines if a pod can request to be run as privileged.
|
||||
Privileged bool `json:"privileged,omitempty"`
|
||||
// capabilities is a list of capabilities that can be added.
|
||||
Capabilities []v1.Capability `json:"capabilities,omitempty"`
|
||||
// volumes is a white list of allowed volume plugins. Empty indicates that all plugins
|
||||
// may be used.
|
||||
Volumes []FSType `json:"volumes,omitempty"`
|
||||
// hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
// hostPorts determines which host port ranges are allowed to be exposed.
|
||||
HostPorts []HostPortRange `json:"hostPorts,omitempty"`
|
||||
// hostPID determines if the policy allows the use of HostPID in the pod spec.
|
||||
HostPID bool `json:"hostPID,omitempty"`
|
||||
// hostIPC determines if the policy allows the use of HostIPC in the pod spec.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// seLinuxContext is the strategy that will dictate the allowable labels that may be set.
|
||||
SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty"`
|
||||
// runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty"`
|
||||
}
|
||||
|
||||
// FS Type gives strong typing to different file systems that are used by volumes.
|
||||
type FSType string
|
||||
|
||||
var (
|
||||
HostPath FSType = "hostPath"
|
||||
EmptyDir FSType = "emptyDir"
|
||||
GCEPersistentDisk FSType = "gcePersistentDisk"
|
||||
AWSElasticBlockStore FSType = "awsElasticBlockStore"
|
||||
GitRepo FSType = "gitRepo"
|
||||
Secret FSType = "secret"
|
||||
NFS FSType = "nfs"
|
||||
ISCSI FSType = "iscsi"
|
||||
Glusterfs FSType = "glusterfs"
|
||||
PersistentVolumeClaim FSType = "persistentVolumeClaim"
|
||||
RBD FSType = "rbd"
|
||||
Cinder FSType = "cinder"
|
||||
CephFS FSType = "cephFS"
|
||||
DownwardAPI FSType = "downwardAPI"
|
||||
FC FSType = "fc"
|
||||
)
|
||||
|
||||
// Host Port Range defines a range of host ports that will be enabled by a policy
|
||||
// for pods to use. It requires both the start and end to be defined.
|
||||
type HostPortRange struct {
|
||||
// min is the start of the range, inclusive.
|
||||
Min int32 `json:"min"`
|
||||
// max is the end of the range, inclusive.
|
||||
Max int32 `json:"max"`
|
||||
}
|
||||
|
||||
// SELinux Context Strategy Options defines the strategy type and any options used to create the strategy.
|
||||
type SELinuxContextStrategyOptions struct {
|
||||
// type is the strategy that will dictate the allowable labels that may be set.
|
||||
Type SELinuxContextStrategy `json:"type"`
|
||||
// seLinuxOptions required to run as; required for MustRunAs
|
||||
// More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context
|
||||
SELinuxOptions *v1.SELinuxOptions `json:"seLinuxOptions,omitempty"`
|
||||
}
|
||||
|
||||
// SELinux Context Strategy Type denotes strategy types for generating SELinux options for a
|
||||
// Security Context.
|
||||
type SELinuxContextStrategy string
|
||||
|
||||
const (
|
||||
// container must have SELinux labels of X applied.
|
||||
SELinuxStrategyMustRunAs SELinuxContextStrategy = "MustRunAs"
|
||||
// container may make requests for any SELinux context labels.
|
||||
SELinuxStrategyRunAsAny SELinuxContextStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// Run A sUser Strategy Options defines the strategy type and any options used to create the strategy.
|
||||
type RunAsUserStrategyOptions struct {
|
||||
// type is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
Type RunAsUserStrategy `json:"type"`
|
||||
// Ranges are the allowed ranges of uids that may be used.
|
||||
Ranges []IDRange `json:"ranges,omitempty"`
|
||||
}
|
||||
|
||||
// ID Range provides a min/max of an allowed range of IDs.
|
||||
type IDRange struct {
|
||||
// Min is the start of the range, inclusive.
|
||||
Min int64 `json:"min"`
|
||||
// Max is the end of the range, inclusive.
|
||||
Max int64 `json:"max"`
|
||||
}
|
||||
|
||||
// Run As User Strategy Type denotes strategy types for generating RunAsUser values for a
|
||||
// Security Context.
|
||||
type RunAsUserStrategy string
|
||||
|
||||
const (
|
||||
// container must run as a particular uid.
|
||||
RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs"
|
||||
// container must run as a non-root uid
|
||||
RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot"
|
||||
// container may make requests for any uid.
|
||||
RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// Pod Security Policy List is a list of PodSecurityPolicy objects.
|
||||
type PodSecurityPolicyList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://docs.k8s.io/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is a list of schema objects.
|
||||
Items []PodSecurityPolicy `json:"items"`
|
||||
}
|
||||
|
|
|
@ -292,6 +292,26 @@ func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string {
|
|||
return map_HorizontalPodAutoscalerStatus
|
||||
}
|
||||
|
||||
var map_HostPortRange = map[string]string{
|
||||
"": "Host Port Range defines a range of host ports that will be enabled by a policy for pods to use. It requires both the start and end to be defined.",
|
||||
"min": "min is the start of the range, inclusive.",
|
||||
"max": "max is the end of the range, inclusive.",
|
||||
}
|
||||
|
||||
func (HostPortRange) SwaggerDoc() map[string]string {
|
||||
return map_HostPortRange
|
||||
}
|
||||
|
||||
var map_IDRange = map[string]string{
|
||||
"": "ID Range provides a min/max of an allowed range of IDs.",
|
||||
"min": "Min is the start of the range, inclusive.",
|
||||
"max": "Max is the end of the range, inclusive.",
|
||||
}
|
||||
|
||||
func (IDRange) SwaggerDoc() map[string]string {
|
||||
return map_IDRange
|
||||
}
|
||||
|
||||
var map_Ingress = map[string]string{
|
||||
"": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.",
|
||||
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
|
@ -464,6 +484,43 @@ func (NodeUtilization) SwaggerDoc() map[string]string {
|
|||
return map_NodeUtilization
|
||||
}
|
||||
|
||||
var map_PodSecurityPolicy = map[string]string{
|
||||
"": "Pod Security Policy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.",
|
||||
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
"spec": "Spec defines the policy enforced.",
|
||||
}
|
||||
|
||||
func (PodSecurityPolicy) SwaggerDoc() map[string]string {
|
||||
return map_PodSecurityPolicy
|
||||
}
|
||||
|
||||
var map_PodSecurityPolicyList = map[string]string{
|
||||
"": "Pod Security Policy List is a list of PodSecurityPolicy objects.",
|
||||
"metadata": "Standard list metadata. More info: http://docs.k8s.io/api-conventions.md#metadata",
|
||||
"items": "Items is a list of schema objects.",
|
||||
}
|
||||
|
||||
func (PodSecurityPolicyList) SwaggerDoc() map[string]string {
|
||||
return map_PodSecurityPolicyList
|
||||
}
|
||||
|
||||
var map_PodSecurityPolicySpec = map[string]string{
|
||||
"": "Pod Security Policy Spec defines the policy enforced.",
|
||||
"privileged": "privileged determines if a pod can request to be run as privileged.",
|
||||
"capabilities": "capabilities is a list of capabilities that can be added.",
|
||||
"volumes": "volumes is a white list of allowed volume plugins. Empty indicates that all plugins may be used.",
|
||||
"hostNetwork": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.",
|
||||
"hostPorts": "hostPorts determines which host port ranges are allowed to be exposed.",
|
||||
"hostPID": "hostPID determines if the policy allows the use of HostPID in the pod spec.",
|
||||
"hostIPC": "hostIPC determines if the policy allows the use of HostIPC in the pod spec.",
|
||||
"seLinuxContext": "seLinuxContext is the strategy that will dictate the allowable labels that may be set.",
|
||||
"runAsUser": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.",
|
||||
}
|
||||
|
||||
func (PodSecurityPolicySpec) SwaggerDoc() map[string]string {
|
||||
return map_PodSecurityPolicySpec
|
||||
}
|
||||
|
||||
var map_ReplicaSet = map[string]string{
|
||||
"": "ReplicaSet represents the configuration of a ReplicaSet.",
|
||||
"metadata": "If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",
|
||||
|
@ -542,6 +599,26 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string {
|
|||
return map_RollingUpdateDeployment
|
||||
}
|
||||
|
||||
var map_RunAsUserStrategyOptions = map[string]string{
|
||||
"": "Run A sUser Strategy Options defines the strategy type and any options used to create the strategy.",
|
||||
"type": "type is the strategy that will dictate the allowable RunAsUser values that may be set.",
|
||||
"ranges": "Ranges are the allowed ranges of uids that may be used.",
|
||||
}
|
||||
|
||||
func (RunAsUserStrategyOptions) SwaggerDoc() map[string]string {
|
||||
return map_RunAsUserStrategyOptions
|
||||
}
|
||||
|
||||
var map_SELinuxContextStrategyOptions = map[string]string{
|
||||
"": "SELinux Context Strategy Options defines the strategy type and any options used to create the strategy.",
|
||||
"type": "type is the strategy that will dictate the allowable labels that may be set.",
|
||||
"seLinuxOptions": "seLinuxOptions required to run as; required for MustRunAs More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context",
|
||||
}
|
||||
|
||||
func (SELinuxContextStrategyOptions) SwaggerDoc() map[string]string {
|
||||
return map_SELinuxContextStrategyOptions
|
||||
}
|
||||
|
||||
var map_Scale = map[string]string{
|
||||
"": "represents a scaling request for a resource.",
|
||||
"metadata": "Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.",
|
||||
|
|
|
@ -697,3 +697,116 @@ func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selecto
|
|||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodSecurityPolicyName can be used to check whether the given
|
||||
// pod security policy name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
func ValidatePodSecurityPolicyName(name string, prefix bool) (bool, string) {
|
||||
return apivalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
func ValidatePodSecurityPolicy(psp *extensions.PodSecurityPolicy) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&psp.ObjectMeta, false, ValidatePodSecurityPolicyName, field.NewPath("metadata"))...)
|
||||
allErrs = append(allErrs, ValidatePodSecurityPolicySpec(&psp.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidatePodSecurityPolicySpec(spec *extensions.PodSecurityPolicySpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
allErrs = append(allErrs, validatePSPRunAsUser(fldPath.Child("runAsUser"), &spec.RunAsUser)...)
|
||||
allErrs = append(allErrs, validatePSPSELinuxContext(fldPath.Child("seLinuxContext"), &spec.SELinuxContext)...)
|
||||
allErrs = append(allErrs, validatePodSecurityPolicyVolumes(fldPath, spec.Volumes)...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePSPSELinuxContext validates the SELinuxContext fields of PodSecurityPolicy.
|
||||
func validatePSPSELinuxContext(fldPath *field.Path, seLinuxContext *extensions.SELinuxContextStrategyOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// ensure the selinux strategy has a valid type
|
||||
supportedSELinuxContextTypes := sets.NewString(string(extensions.SELinuxStrategyMustRunAs),
|
||||
string(extensions.SELinuxStrategyRunAsAny))
|
||||
if !supportedSELinuxContextTypes.Has(string(seLinuxContext.Type)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("type"), seLinuxContext.Type, supportedSELinuxContextTypes.List()))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePSPRunAsUser validates the RunAsUser fields of PodSecurityPolicy.
|
||||
func validatePSPRunAsUser(fldPath *field.Path, runAsUser *extensions.RunAsUserStrategyOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// ensure the user strategy has a valid type
|
||||
supportedRunAsUserTypes := sets.NewString(string(extensions.RunAsUserStrategyMustRunAs),
|
||||
string(extensions.RunAsUserStrategyMustRunAsNonRoot),
|
||||
string(extensions.RunAsUserStrategyRunAsAny))
|
||||
if !supportedRunAsUserTypes.Has(string(runAsUser.Type)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("type"), runAsUser.Type, supportedRunAsUserTypes.List()))
|
||||
}
|
||||
|
||||
// validate range settings
|
||||
for idx, rng := range runAsUser.Ranges {
|
||||
allErrs = append(allErrs, validateIDRanges(fldPath.Child("ranges").Index(idx), rng)...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePodSecurityPolicyVolumes validates the volume fields of PodSecurityPolicy.
|
||||
func validatePodSecurityPolicyVolumes(fldPath *field.Path, volumes []extensions.FSType) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allowed := sets.NewString(string(extensions.HostPath),
|
||||
string(extensions.EmptyDir),
|
||||
string(extensions.GCEPersistentDisk),
|
||||
string(extensions.AWSElasticBlockStore),
|
||||
string(extensions.GitRepo),
|
||||
string(extensions.Secret),
|
||||
string(extensions.NFS),
|
||||
string(extensions.ISCSI),
|
||||
string(extensions.Glusterfs),
|
||||
string(extensions.PersistentVolumeClaim),
|
||||
string(extensions.RBD),
|
||||
string(extensions.Cinder),
|
||||
string(extensions.CephFS),
|
||||
string(extensions.DownwardAPI),
|
||||
string(extensions.FC))
|
||||
for _, v := range volumes {
|
||||
if !allowed.Has(string(v)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("volumes"), v, allowed.List()))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateIDRanges ensures the range is valid.
|
||||
func validateIDRanges(fldPath *field.Path, rng extensions.IDRange) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// if 0 <= Min <= Max then we do not need to validate max. It is always greater than or
|
||||
// equal to 0 and Min.
|
||||
if rng.Min < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("min"), rng.Min, "min cannot be negative"))
|
||||
}
|
||||
if rng.Max < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("max"), rng.Max, "max cannot be negative"))
|
||||
}
|
||||
if rng.Min > rng.Max {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("min"), rng.Min, "min cannot be greater than max"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodSecurityPolicyUpdate validates a PSP for updates.
|
||||
func ValidatePodSecurityPolicyUpdate(old *extensions.PodSecurityPolicy, new *extensions.PodSecurityPolicy) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&old.ObjectMeta, &new.ObjectMeta, field.NewPath("metadata"))...)
|
||||
allErrs = append(allErrs, ValidatePodSecurityPolicySpec(&new.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
|
|
@ -1977,3 +1977,126 @@ func newInt(val int) *int {
|
|||
*p = val
|
||||
return p
|
||||
}
|
||||
|
||||
func TestValidatePodSecurityPolicy(t *testing.T) {
|
||||
validSCC := func() *extensions.PodSecurityPolicy {
|
||||
return &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: extensions.PodSecurityPolicySpec{
|
||||
SELinuxContext: extensions.SELinuxContextStrategyOptions{
|
||||
Type: extensions.SELinuxStrategyRunAsAny,
|
||||
},
|
||||
RunAsUser: extensions.RunAsUserStrategyOptions{
|
||||
Type: extensions.RunAsUserStrategyRunAsAny,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
noUserOptions := validSCC()
|
||||
noUserOptions.Spec.RunAsUser.Type = ""
|
||||
|
||||
noSELinuxOptions := validSCC()
|
||||
noSELinuxOptions.Spec.SELinuxContext.Type = ""
|
||||
|
||||
invalidUserStratType := validSCC()
|
||||
invalidUserStratType.Spec.RunAsUser.Type = "invalid"
|
||||
|
||||
invalidSELinuxStratType := validSCC()
|
||||
invalidSELinuxStratType.Spec.SELinuxContext.Type = "invalid"
|
||||
|
||||
missingObjectMetaName := validSCC()
|
||||
missingObjectMetaName.ObjectMeta.Name = ""
|
||||
|
||||
invalidRangeMinGreaterThanMax := validSCC()
|
||||
invalidRangeMinGreaterThanMax.Spec.RunAsUser.Ranges = []extensions.IDRange{
|
||||
{Min: 2, Max: 1},
|
||||
}
|
||||
|
||||
invalidRangeNegativeMin := validSCC()
|
||||
invalidRangeNegativeMin.Spec.RunAsUser.Ranges = []extensions.IDRange{
|
||||
{Min: -1, Max: 10},
|
||||
}
|
||||
|
||||
invalidRangeNegativeMax := validSCC()
|
||||
invalidRangeNegativeMax.Spec.RunAsUser.Ranges = []extensions.IDRange{
|
||||
{Min: 1, Max: -10},
|
||||
}
|
||||
|
||||
errorCases := map[string]struct {
|
||||
scc *extensions.PodSecurityPolicy
|
||||
errorDetail string
|
||||
}{
|
||||
"no user options": {
|
||||
scc: noUserOptions,
|
||||
errorDetail: "supported values: MustRunAs, MustRunAsNonRoot, RunAsAny",
|
||||
},
|
||||
"no selinux options": {
|
||||
scc: noSELinuxOptions,
|
||||
errorDetail: "supported values: MustRunAs, RunAsAny",
|
||||
},
|
||||
"invalid user strategy type": {
|
||||
scc: invalidUserStratType,
|
||||
errorDetail: "supported values: MustRunAs, MustRunAsNonRoot, RunAsAny",
|
||||
},
|
||||
"invalid selinux strategy type": {
|
||||
scc: invalidSELinuxStratType,
|
||||
errorDetail: "supported values: MustRunAs, RunAsAny",
|
||||
},
|
||||
"missing object meta name": {
|
||||
scc: missingObjectMetaName,
|
||||
errorDetail: "name or generateName is required",
|
||||
},
|
||||
"invalid range min greater than max": {
|
||||
scc: invalidRangeMinGreaterThanMax,
|
||||
errorDetail: "min cannot be greater than max",
|
||||
},
|
||||
"invalid range negative min": {
|
||||
scc: invalidRangeNegativeMin,
|
||||
errorDetail: "min cannot be negative",
|
||||
},
|
||||
"invalid range negative max": {
|
||||
scc: invalidRangeNegativeMax,
|
||||
errorDetail: "max cannot be negative",
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range errorCases {
|
||||
if errs := ValidatePodSecurityPolicy(v.scc); len(errs) == 0 || errs[0].Detail != v.errorDetail {
|
||||
t.Errorf("Expected error with detail %s for %s, got %v", v.errorDetail, k, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
|
||||
mustRunAs := validSCC()
|
||||
mustRunAs.Spec.RunAsUser.Type = extensions.RunAsUserStrategyMustRunAs
|
||||
mustRunAs.Spec.RunAsUser.Ranges = []extensions.IDRange{
|
||||
{
|
||||
Min: 1,
|
||||
Max: 1,
|
||||
},
|
||||
}
|
||||
mustRunAs.Spec.SELinuxContext.Type = extensions.SELinuxStrategyMustRunAs
|
||||
|
||||
runAsNonRoot := validSCC()
|
||||
runAsNonRoot.Spec.RunAsUser.Type = extensions.RunAsUserStrategyMustRunAsNonRoot
|
||||
|
||||
successCases := map[string]struct {
|
||||
scc *extensions.PodSecurityPolicy
|
||||
}{
|
||||
"must run as": {
|
||||
scc: mustRunAs,
|
||||
},
|
||||
"run as any": {
|
||||
scc: validSCC(),
|
||||
},
|
||||
"run as non-root (user only)": {
|
||||
scc: runAsNonRoot,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range successCases {
|
||||
if errs := ValidatePodSecurityPolicy(v.scc); len(errs) != 0 {
|
||||
t.Errorf("Expected success for %s, got %v", k, errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ type ExtensionsInterface interface {
|
|||
IngressNamespacer
|
||||
ThirdPartyResourceNamespacer
|
||||
ReplicaSetsNamespacer
|
||||
PodSecurityPoliciesInterface
|
||||
}
|
||||
|
||||
// ExtensionsClient is used to interact with experimental Kubernetes features.
|
||||
|
@ -44,6 +45,10 @@ type ExtensionsClient struct {
|
|||
*RESTClient
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) PodSecurityPolicies() PodSecurityPolicyInterface {
|
||||
return newPodSecurityPolicy(c)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface {
|
||||
return newHorizontalPodAutoscalers(c, namespace)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
type PodSecurityPoliciesInterface interface {
|
||||
PodSecurityPolicies() PodSecurityPolicyInterface
|
||||
}
|
||||
|
||||
type PodSecurityPolicyInterface interface {
|
||||
Get(name string) (result *extensions.PodSecurityPolicy, err error)
|
||||
Create(scc *extensions.PodSecurityPolicy) (*extensions.PodSecurityPolicy, error)
|
||||
List(opts api.ListOptions) (*extensions.PodSecurityPolicyList, error)
|
||||
Delete(name string) error
|
||||
Update(*extensions.PodSecurityPolicy) (*extensions.PodSecurityPolicy, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
// podSecurityPolicy implements PodSecurityPolicyInterface
|
||||
type podSecurityPolicy struct {
|
||||
client *ExtensionsClient
|
||||
}
|
||||
|
||||
// newPodSecurityPolicy returns a podSecurityPolicy object.
|
||||
func newPodSecurityPolicy(c *ExtensionsClient) *podSecurityPolicy {
|
||||
return &podSecurityPolicy{c}
|
||||
}
|
||||
|
||||
func (s *podSecurityPolicy) Create(scc *extensions.PodSecurityPolicy) (*extensions.PodSecurityPolicy, error) {
|
||||
result := &extensions.PodSecurityPolicy{}
|
||||
err := s.client.Post().
|
||||
Resource("podsecuritypolicies").
|
||||
Body(scc).
|
||||
Do().
|
||||
Into(result)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
// List returns a list of PodSecurityPolicies matching the selectors.
|
||||
func (s *podSecurityPolicy) List(opts api.ListOptions) (*extensions.PodSecurityPolicyList, error) {
|
||||
result := &extensions.PodSecurityPolicyList{}
|
||||
|
||||
err := s.client.Get().
|
||||
Resource("podsecuritypolicies").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Get returns the given PodSecurityPolicy, or an error.
|
||||
func (s *podSecurityPolicy) Get(name string) (*extensions.PodSecurityPolicy, error) {
|
||||
result := &extensions.PodSecurityPolicy{}
|
||||
err := s.client.Get().
|
||||
Resource("podsecuritypolicies").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Watch starts watching for PodSecurityPolicies matching the given selectors.
|
||||
func (s *podSecurityPolicy) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return s.client.Get().
|
||||
Prefix("watch").
|
||||
Resource("podsecuritypolicies").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
|
||||
func (s *podSecurityPolicy) Delete(name string) error {
|
||||
return s.client.Delete().
|
||||
Resource("podsecuritypolicies").
|
||||
Name(name).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
func (s *podSecurityPolicy) Update(psp *extensions.PodSecurityPolicy) (result *extensions.PodSecurityPolicy, err error) {
|
||||
result = &extensions.PodSecurityPolicy{}
|
||||
err = s.client.Put().
|
||||
Resource("podsecuritypolicies").
|
||||
Name(psp.Name).
|
||||
Body(psp).
|
||||
Do().
|
||||
Into(result)
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
. "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient/simple"
|
||||
)
|
||||
|
||||
func TestPodSecurityPolicyCreate(t *testing.T) {
|
||||
ns := api.NamespaceNone
|
||||
scc := &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
},
|
||||
}
|
||||
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{
|
||||
Method: "POST",
|
||||
Path: testapi.Extensions.ResourcePath(getPSPResourcename(), ns, ""),
|
||||
Query: simple.BuildQueryValues(nil),
|
||||
Body: scc,
|
||||
},
|
||||
Response: simple.Response{StatusCode: 200, Body: scc},
|
||||
}
|
||||
|
||||
response, err := c.Setup(t).PodSecurityPolicies().Create(scc)
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
func TestPodSecurityPolicyGet(t *testing.T) {
|
||||
ns := api.NamespaceNone
|
||||
scc := &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
},
|
||||
}
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{
|
||||
Method: "GET",
|
||||
Path: testapi.Extensions.ResourcePath(getPSPResourcename(), ns, "abc"),
|
||||
Query: simple.BuildQueryValues(nil),
|
||||
Body: nil,
|
||||
},
|
||||
Response: simple.Response{StatusCode: 200, Body: scc},
|
||||
}
|
||||
|
||||
response, err := c.Setup(t).PodSecurityPolicies().Get("abc")
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
func TestPodSecurityPolicyList(t *testing.T) {
|
||||
ns := api.NamespaceNone
|
||||
sccList := &extensions.PodSecurityPolicyList{
|
||||
Items: []extensions.PodSecurityPolicy{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{
|
||||
Method: "GET",
|
||||
Path: testapi.Extensions.ResourcePath(getPSPResourcename(), ns, ""),
|
||||
Query: simple.BuildQueryValues(nil),
|
||||
Body: nil,
|
||||
},
|
||||
Response: simple.Response{StatusCode: 200, Body: sccList},
|
||||
}
|
||||
response, err := c.Setup(t).PodSecurityPolicies().List(api.ListOptions{})
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
func TestPodSecurityPolicyUpdate(t *testing.T) {
|
||||
ns := api.NamespaceNone
|
||||
scc := &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "abc",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
}
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{Method: "PUT", Path: testapi.Extensions.ResourcePath(getPSPResourcename(), ns, "abc"), Query: simple.BuildQueryValues(nil)},
|
||||
Response: simple.Response{StatusCode: 200, Body: scc},
|
||||
}
|
||||
response, err := c.Setup(t).PodSecurityPolicies().Update(scc)
|
||||
c.Validate(t, response, err)
|
||||
}
|
||||
|
||||
func TestPodSecurityPolicyDelete(t *testing.T) {
|
||||
ns := api.NamespaceNone
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{Method: "DELETE", Path: testapi.Extensions.ResourcePath(getPSPResourcename(), ns, "foo"), Query: simple.BuildQueryValues(nil)},
|
||||
Response: simple.Response{StatusCode: 200},
|
||||
}
|
||||
err := c.Setup(t).PodSecurityPolicies().Delete("foo")
|
||||
c.Validate(t, nil, err)
|
||||
}
|
||||
|
||||
func TestPodSecurityPolicyWatch(t *testing.T) {
|
||||
c := &simple.Client{
|
||||
Request: simple.Request{
|
||||
Method: "GET",
|
||||
Path: fmt.Sprintf("%s/watch/%s", testapi.Extensions.ResourcePath("", "", ""), getPSPResourcename()),
|
||||
Query: url.Values{"resourceVersion": []string{}}},
|
||||
Response: simple.Response{StatusCode: 200},
|
||||
}
|
||||
_, err := c.Setup(t).PodSecurityPolicies().Watch(api.ListOptions{})
|
||||
c.Validate(t, nil, err)
|
||||
}
|
||||
|
||||
func getPSPResourcename() string {
|
||||
return "podsecuritypolicies"
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testclient
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// FakePodSecurityPolicy implements PodSecurityPolicyInterface. Meant to be
|
||||
// embedded into a struct to get a default implementation. This makes faking out just
|
||||
// the method you want to test easier.
|
||||
type FakePodSecurityPolicy struct {
|
||||
Fake *Fake
|
||||
Namespace string
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) List(opts api.ListOptions) (*extensions.PodSecurityPolicyList, error) {
|
||||
obj, err := c.Fake.Invokes(NewListAction("podsecuritypolicies", c.Namespace, opts), &extensions.PodSecurityPolicyList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*extensions.PodSecurityPolicyList), err
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) Get(name string) (*extensions.PodSecurityPolicy, error) {
|
||||
obj, err := c.Fake.Invokes(NewGetAction("podsecuritypolicies", c.Namespace, name), &extensions.PodSecurityPolicy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.PodSecurityPolicy), err
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) Create(scc *extensions.PodSecurityPolicy) (*extensions.PodSecurityPolicy, error) {
|
||||
obj, err := c.Fake.Invokes(NewCreateAction("podsecuritypolicies", c.Namespace, scc), &extensions.PodSecurityPolicy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.PodSecurityPolicy), err
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) Update(scc *extensions.PodSecurityPolicy) (*extensions.PodSecurityPolicy, error) {
|
||||
obj, err := c.Fake.Invokes(NewUpdateAction("podsecuritypolicies", c.Namespace, scc), &extensions.PodSecurityPolicy{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*extensions.PodSecurityPolicy), err
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) Delete(name string) error {
|
||||
_, err := c.Fake.Invokes(NewDeleteAction("podsecuritypolicies", c.Namespace, name), &extensions.PodSecurityPolicy{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePodSecurityPolicy) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.InvokesWatch(NewWatchAction("podsecuritypolicies", c.Namespace, opts))
|
||||
}
|
|
@ -230,6 +230,10 @@ func (c *Fake) Nodes() client.NodeInterface {
|
|||
return &FakeNodes{Fake: c}
|
||||
}
|
||||
|
||||
func (c *Fake) PodSecurityPolicies() client.PodSecurityPolicyInterface {
|
||||
return &FakePodSecurityPolicy{Fake: c}
|
||||
}
|
||||
|
||||
func (c *Fake) Events(namespace string) client.EventInterface {
|
||||
return &FakeEvents{Fake: c, Namespace: namespace}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ func expandResourceShortcut(resource unversioned.GroupVersionResource) unversion
|
|||
"no": api.SchemeGroupVersion.WithResource("nodes"),
|
||||
"ns": api.SchemeGroupVersion.WithResource("namespaces"),
|
||||
"po": api.SchemeGroupVersion.WithResource("pods"),
|
||||
"psp": api.SchemeGroupVersion.WithResource("podSecurityPolicies"),
|
||||
"pvc": api.SchemeGroupVersion.WithResource("persistentvolumeclaims"),
|
||||
"pv": api.SchemeGroupVersion.WithResource("persistentvolumes"),
|
||||
"quota": api.SchemeGroupVersion.WithResource("resourcequotas"),
|
||||
|
|
|
@ -415,6 +415,7 @@ var horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CU
|
|||
var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
|
||||
var deploymentColumns = []string{"NAME", "DESIRED", "CURRENT", "UP-TO-DATE", "AVAILABLE", "AGE"}
|
||||
var configMapColumns = []string{"NAME", "DATA", "AGE"}
|
||||
var podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "VOLUMEPLUGINS", "SELINUX", "RUNASUSER"}
|
||||
|
||||
// addDefaultHandlers adds print handlers for default Kubernetes types.
|
||||
func (h *HumanReadablePrinter) addDefaultHandlers() {
|
||||
|
@ -462,6 +463,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
|
|||
h.Handler(horizontalPodAutoscalerColumns, printHorizontalPodAutoscalerList)
|
||||
h.Handler(configMapColumns, printConfigMap)
|
||||
h.Handler(configMapColumns, printConfigMapList)
|
||||
h.Handler(podSecurityPolicyColumns, printPodSecurityPolicy)
|
||||
h.Handler(podSecurityPolicyColumns, printPodSecurityPolicyList)
|
||||
}
|
||||
|
||||
func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error {
|
||||
|
@ -1478,6 +1481,23 @@ func printConfigMapList(list *api.ConfigMapList, w io.Writer, options PrintOptio
|
|||
return nil
|
||||
}
|
||||
|
||||
func printPodSecurityPolicy(item *extensions.PodSecurityPolicy, w io.Writer, options PrintOptions) error {
|
||||
_, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%s\t%s\n", item.Name, item.Spec.Privileged,
|
||||
item.Spec.Capabilities, item.Spec.Volumes, item.Spec.SELinuxContext.Type,
|
||||
item.Spec.RunAsUser.Type)
|
||||
return err
|
||||
}
|
||||
|
||||
func printPodSecurityPolicyList(list *extensions.PodSecurityPolicyList, w io.Writer, options PrintOptions) error {
|
||||
for _, item := range list.Items {
|
||||
if err := printPodSecurityPolicy(&item, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendLabels(itemLabels map[string]string, columnLabels []string) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import (
|
|||
pvetcd "k8s.io/kubernetes/pkg/registry/persistentvolume/etcd"
|
||||
pvcetcd "k8s.io/kubernetes/pkg/registry/persistentvolumeclaim/etcd"
|
||||
podetcd "k8s.io/kubernetes/pkg/registry/pod/etcd"
|
||||
pspetcd "k8s.io/kubernetes/pkg/registry/podsecuritypolicy/etcd"
|
||||
podtemplateetcd "k8s.io/kubernetes/pkg/registry/podtemplate/etcd"
|
||||
resourcequotaetcd "k8s.io/kubernetes/pkg/registry/resourcequota/etcd"
|
||||
secretetcd "k8s.io/kubernetes/pkg/registry/secret/etcd"
|
||||
|
@ -587,7 +588,7 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV
|
|||
// getExperimentalResources returns the resources for extenstions api
|
||||
func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage {
|
||||
// All resources except these are disabled by default.
|
||||
enabledResources := sets.NewString("jobs", "horizontalpodautoscalers", "ingresses")
|
||||
enabledResources := sets.NewString("jobs", "horizontalpodautoscalers", "ingresses", "podsecuritypolicy")
|
||||
resourceOverrides := m.ApiGroupVersionOverrides["extensions/v1beta1"].ResourceOverrides
|
||||
isEnabled := func(resource string) bool {
|
||||
// Check if the resource has been overriden.
|
||||
|
@ -650,6 +651,10 @@ func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage {
|
|||
storage["ingresses"] = ingressStorage
|
||||
storage["ingresses/status"] = ingressStatusStorage
|
||||
}
|
||||
if isEnabled("podsecuritypolicy") {
|
||||
podSecurityPolicyStorage := pspetcd.NewREST(dbClient("podsecuritypolicy"), storageDecorator)
|
||||
storage["podSecurityPolicies"] = podSecurityPolicyStorage
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package podsecuritypolicy provides Registry interface and its REST
|
||||
// implementation for storing PodSecurityPolicy api objects.
|
||||
package podsecuritypolicy
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
||||
"k8s.io/kubernetes/pkg/registry/podsecuritypolicy"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
)
|
||||
|
||||
// REST implements a RESTStorage for PodSecurityPolicies against etcd.
|
||||
type REST struct {
|
||||
*etcdgeneric.Etcd
|
||||
}
|
||||
|
||||
const Prefix = "/podsecuritypolicies"
|
||||
|
||||
// NewREST returns a RESTStorage object that will work against PodSecurityPolicy objects.
|
||||
func NewREST(s storage.Interface, storageDecorator generic.StorageDecorator) *REST {
|
||||
newListFunc := func() runtime.Object { return &extensions.PodSecurityPolicyList{} }
|
||||
storageInterface := storageDecorator(
|
||||
s, 100, &extensions.PodSecurityPolicy{}, Prefix, podsecuritypolicy.Strategy, newListFunc)
|
||||
|
||||
store := &etcdgeneric.Etcd{
|
||||
NewFunc: func() runtime.Object { return &extensions.PodSecurityPolicy{} },
|
||||
NewListFunc: newListFunc,
|
||||
KeyRootFunc: func(ctx api.Context) string {
|
||||
return Prefix
|
||||
},
|
||||
KeyFunc: func(ctx api.Context, name string) (string, error) {
|
||||
return etcdgeneric.NoNamespaceKeyFunc(ctx, Prefix, name)
|
||||
},
|
||||
ObjectNameFunc: func(obj runtime.Object) (string, error) {
|
||||
return obj.(*extensions.PodSecurityPolicy).Name, nil
|
||||
},
|
||||
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return podsecuritypolicy.MatchPodSecurityPolicy(label, field)
|
||||
},
|
||||
QualifiedResource: extensions.Resource("podsecuritypolicies"),
|
||||
|
||||
CreateStrategy: podsecuritypolicy.Strategy,
|
||||
UpdateStrategy: podsecuritypolicy.Strategy,
|
||||
ReturnDeletedObject: true,
|
||||
Storage: storageInterface,
|
||||
}
|
||||
return &REST{store}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
// Ensure that extensions/v1beta1 package is initialized.
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
|
||||
etcdStorage, server := registrytest.NewEtcdStorage(t, "extensions")
|
||||
return NewREST(etcdStorage, generic.UndecoratedStorage), server
|
||||
}
|
||||
|
||||
func validNewPodSecurityPolicy() *extensions.PodSecurityPolicy {
|
||||
return &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: extensions.PodSecurityPolicySpec{
|
||||
SELinuxContext: extensions.SELinuxContextStrategyOptions{
|
||||
Type: extensions.SELinuxStrategyRunAsAny,
|
||||
},
|
||||
RunAsUser: extensions.RunAsUserStrategyOptions{
|
||||
Type: extensions.RunAsUserStrategyRunAsAny,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope()
|
||||
scc := validNewPodSecurityPolicy()
|
||||
scc.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
scc,
|
||||
// invalid
|
||||
&extensions.PodSecurityPolicy{
|
||||
ObjectMeta: api.ObjectMeta{Name: "name with spaces"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope()
|
||||
test.TestUpdate(
|
||||
// valid
|
||||
validNewPodSecurityPolicy(),
|
||||
// updateFunc
|
||||
func(obj runtime.Object) runtime.Object {
|
||||
object := obj.(*extensions.PodSecurityPolicy)
|
||||
object.Labels = map[string]string{"a": "b"}
|
||||
return object
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope().ReturnDeletedObject()
|
||||
test.TestDelete(validNewPodSecurityPolicy())
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope()
|
||||
test.TestGet(validNewPodSecurityPolicy())
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope()
|
||||
test.TestList(validNewPodSecurityPolicy())
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
storage, server := newStorage(t)
|
||||
defer server.Terminate(t)
|
||||
test := registrytest.New(t, storage.Etcd).ClusterScope()
|
||||
test.TestWatch(
|
||||
validNewPodSecurityPolicy(),
|
||||
// matching labels
|
||||
[]labels.Set{},
|
||||
// not matching labels
|
||||
[]labels.Set{
|
||||
{"foo": "bar"},
|
||||
},
|
||||
// matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "foo"},
|
||||
},
|
||||
// not matching fields
|
||||
[]fields.Set{
|
||||
{"metadata.name": "bar"},
|
||||
{"name": "foo"},
|
||||
},
|
||||
)
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package podsecuritypolicy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions/validation"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/generic"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// strategy implements behavior for PodSecurityPolicy objects
|
||||
type strategy struct {
|
||||
runtime.ObjectTyper
|
||||
api.NameGenerator
|
||||
}
|
||||
|
||||
// Strategy is the default logic that applies when creating and updating PodSecurityPolicy
|
||||
// objects via the REST API.
|
||||
var Strategy = strategy{api.Scheme, api.SimpleNameGenerator}
|
||||
|
||||
var _ = rest.RESTCreateStrategy(Strategy)
|
||||
|
||||
var _ = rest.RESTUpdateStrategy(Strategy)
|
||||
|
||||
func (strategy) NamespaceScoped() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (strategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (strategy) AllowUnconditionalUpdate() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (strategy) PrepareForCreate(obj runtime.Object) {
|
||||
}
|
||||
|
||||
func (strategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
}
|
||||
|
||||
func (strategy) Canonicalize(obj runtime.Object) {
|
||||
}
|
||||
|
||||
func (strategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList {
|
||||
return validation.ValidatePodSecurityPolicy(obj.(*extensions.PodSecurityPolicy))
|
||||
}
|
||||
|
||||
func (strategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList {
|
||||
return validation.ValidatePodSecurityPolicyUpdate(old.(*extensions.PodSecurityPolicy), obj.(*extensions.PodSecurityPolicy))
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
func MatchPodSecurityPolicy(label labels.Selector, field fields.Selector) generic.Matcher {
|
||||
return &generic.SelectionPredicate{
|
||||
Label: label,
|
||||
Field: field,
|
||||
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
psp, ok := obj.(*extensions.PodSecurityPolicy)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a pod security policy.")
|
||||
}
|
||||
return labels.Set(psp.ObjectMeta.Labels), PodSecurityPolicyToSelectableFields(psp), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PodSecurityPolicyToSelectableFields returns a label set that represents the object
|
||||
func PodSecurityPolicyToSelectableFields(obj *extensions.PodSecurityPolicy) fields.Set {
|
||||
return generic.ObjectMetaFieldsSet(obj.ObjectMeta, false)
|
||||
}
|
Loading…
Reference in New Issue