Commit 5f9447a9 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #20573 from deads2k/plumb-in-SAR

Automatic merge from submit-queue add subjectaccessreviews resource Adds a subjectaccessreviews endpoint that uses the API server's authorizer to determine if a subject is allowed to perform an action. Part of kubernetes/features#37
parents 4c7c408c d9a20340
{
"swaggerVersion": "1.2",
"apiVersion": "",
"basePath": "https://10.10.10.10:6443",
"resourcePath": "/apis/authorization.k8s.io",
"apis": [
{
"path": "/apis/authorization.k8s.io",
"description": "get information of a group",
"operations": [
{
"type": "unversioned.APIGroup",
"method": "GET",
"summary": "get information of a group",
"nickname": "getAPIGroup",
"parameters": [],
"produces": [
"application/json",
"application/yaml",
"application/vnd.kubernetes.protobuf"
],
"consumes": [
"application/json",
"application/yaml",
"application/vnd.kubernetes.protobuf"
]
}
]
}
],
"models": {
"unversioned.APIGroup": {
"id": "unversioned.APIGroup",
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
"required": [
"name",
"versions",
"serverAddressByClientCIDRs"
],
"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"
},
"name": {
"type": "string",
"description": "name is the name of the group."
},
"versions": {
"type": "array",
"items": {
"$ref": "unversioned.GroupVersionForDiscovery"
},
"description": "versions are the versions supported in this group."
},
"preferredVersion": {
"$ref": "unversioned.GroupVersionForDiscovery",
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version."
},
"serverAddressByClientCIDRs": {
"type": "array",
"items": {
"$ref": "unversioned.ServerAddressByClientCIDR"
},
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP."
}
}
},
"unversioned.GroupVersionForDiscovery": {
"id": "unversioned.GroupVersionForDiscovery",
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
"required": [
"groupVersion",
"version"
],
"properties": {
"groupVersion": {
"type": "string",
"description": "groupVersion specifies the API group and version in the form \"group/version\""
},
"version": {
"type": "string",
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion."
}
}
},
"unversioned.ServerAddressByClientCIDR": {
"id": "unversioned.ServerAddressByClientCIDR",
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
"required": [
"clientCIDR",
"serverAddress"
],
"properties": {
"clientCIDR": {
"type": "string",
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use."
},
"serverAddress": {
"type": "string",
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port."
}
}
}
}
}
...@@ -34,6 +34,14 @@ ...@@ -34,6 +34,14 @@
"description": "get information of a group" "description": "get information of a group"
}, },
{ {
"path": "/apis/authorization.k8s.io/v1beta1",
"description": "API at /apis/authorization.k8s.io/v1beta1"
},
{
"path": "/apis/authorization.k8s.io",
"description": "get information of a group"
},
{
"path": "/apis/autoscaling/v1", "path": "/apis/autoscaling/v1",
"description": "API at /apis/autoscaling/v1" "description": "API at /apis/autoscaling/v1"
}, },
......
...@@ -32,8 +32,17 @@ import ( ...@@ -32,8 +32,17 @@ import (
) )
var ( var (
test = flag.BoolP("test", "t", false, "set this flag to generate the client code for the testdata") test = flag.BoolP("test", "t", false, "set this flag to generate the client code for the testdata")
inputVersions = flag.StringSlice("input", []string{"api/", "extensions/", "autoscaling/", "authentication/", "batch/", "rbac/", "certificates/"}, "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\". Default to \"api/,extensions/,autoscaling/,batch/,rbac/\"") inputVersions = flag.StringSlice("input", []string{
"api/",
"authentication/",
"authorization/",
"autoscaling/",
"batch/",
"certificates/",
"extensions/",
"rbac/",
}, "group/versions that client-gen will generate clients for. At most one version per group is allowed. Specified in the format \"group1/version1,group2/version2...\". Default to \"api/,extensions/,autoscaling/,batch/,rbac/\"")
includedTypesOverrides = flag.StringSlice("included-types-overrides", []string{}, "list of group/version/type for which client should be generated. By default, client is generated for all types which have genclient=true in types.go. This overrides that. For each groupVersion in this list, only the types mentioned here will be included. The default check of genclient=true will be used for other group versions.") includedTypesOverrides = flag.StringSlice("included-types-overrides", []string{}, "list of group/version/type for which client should be generated. By default, client is generated for all types which have genclient=true in types.go. This overrides that. For each groupVersion in this list, only the types mentioned here will be included. The default check of genclient=true will be used for other group versions.")
basePath = flag.String("input-base", "k8s.io/kubernetes/pkg/apis", "base path to look for the api group. Default to \"k8s.io/kubernetes/pkg/apis\"") basePath = flag.String("input-base", "k8s.io/kubernetes/pkg/apis", "base path to look for the api group. Default to \"k8s.io/kubernetes/pkg/apis\"")
clientsetName = flag.StringP("clientset-name", "n", "internalclientset", "the name of the generated clientset package.") clientsetName = flag.StringP("clientset-name", "n", "internalclientset", "the name of the generated clientset package.")
......
...@@ -69,6 +69,7 @@ func New() *Generator { ...@@ -69,6 +69,7 @@ func New() *Generator {
`k8s.io/kubernetes/pkg/apis/policy/v1alpha1`, `k8s.io/kubernetes/pkg/apis/policy/v1alpha1`,
`k8s.io/kubernetes/pkg/apis/extensions/v1beta1`, `k8s.io/kubernetes/pkg/apis/extensions/v1beta1`,
`k8s.io/kubernetes/pkg/apis/autoscaling/v1`, `k8s.io/kubernetes/pkg/apis/autoscaling/v1`,
`k8s.io/kubernetes/pkg/apis/authorization/v1beta1`,
`k8s.io/kubernetes/pkg/apis/batch/v1`, `k8s.io/kubernetes/pkg/apis/batch/v1`,
`k8s.io/kubernetes/pkg/apis/batch/v2alpha1`, `k8s.io/kubernetes/pkg/apis/batch/v2alpha1`,
`k8s.io/kubernetes/pkg/apis/apps/v1alpha1`, `k8s.io/kubernetes/pkg/apis/apps/v1alpha1`,
......
...@@ -2328,6 +2328,26 @@ __EOF__ ...@@ -2328,6 +2328,26 @@ __EOF__
kubectl create -f test/fixtures/pkg/kubectl/cmd/create/tokenreview.json --validate=false kubectl create -f test/fixtures/pkg/kubectl/cmd/create/tokenreview.json --validate=false
########################
# authorization.k8s.io #
########################
# check remote authorization endpoint, kubectl doesn't actually display the returned object so this isn't super useful
# but it proves that works
kubectl create -f test/fixtures/pkg/kubectl/cmd/create/sar.json --validate=false
SAR_RESULT_FILE="${KUBE_TEMP}/sar-result.json"
curl -k -H "Content-Type:" http://localhost:8080/apis/authorization.k8s.io/v1beta1/subjectaccessreviews -XPOST -d @test/fixtures/pkg/kubectl/cmd/create/sar.json > "${SAR_RESULT_FILE}"
if grep -q '"allowed": true' "${SAR_RESULT_FILE}"; then
kube::log::status "\"authorization.k8s.io/subjectaccessreviews\" returns as expected: $(cat "${SAR_RESULT_FILE}")"
else
kube::log::status "\"authorization.k8s.io/subjectaccessreviews\" does not return as expected: $(cat "${SAR_RESULT_FILE}")"
exit 1
fi
rm "${SAR_RESULT_FILE}"
##################### #####################
# Retrieve multiple # # Retrieve multiple #
##################### #####################
......
...@@ -27,7 +27,7 @@ source "${KUBE_ROOT}/hack/lib/init.sh" ...@@ -27,7 +27,7 @@ source "${KUBE_ROOT}/hack/lib/init.sh"
# KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,extensions/v1beta1"} # KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,extensions/v1beta1"}
# FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go) # FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go)
# ONLY the last version is tested in each group. # ONLY the last version is tested in each group.
KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,autoscaling/v1,batch/v1,apps/v1alpha1,policy/v1alpha1,extensions/v1beta1,rbac.authorization.k8s.io/v1alpha1,certificates/v1alpha1"} KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,authorization.k8s.io/v1beta1,autoscaling/v1,batch/v1,apps/v1alpha1,policy/v1alpha1,extensions/v1beta1,rbac.authorization.k8s.io/v1alpha1,certificates/v1alpha1"}
# Give integration tests longer to run # Give integration tests longer to run
# TODO: allow a larger value to be passed in # TODO: allow a larger value to be passed in
......
...@@ -60,7 +60,7 @@ KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-} ...@@ -60,7 +60,7 @@ KUBE_GOVERALLS_BIN=${KUBE_GOVERALLS_BIN:-}
# "v1,compute/v1alpha1,experimental/v1alpha2;v1,compute/v2,experimental/v1alpha3" # "v1,compute/v1alpha1,experimental/v1alpha2;v1,compute/v2,experimental/v1alpha3"
# FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go) # FIXME: due to current implementation of a test client (see: pkg/api/testapi/testapi.go)
# ONLY the last version is tested in each group. # ONLY the last version is tested in each group.
KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,autoscaling/v1,authentication.k8s.io/v1beta1,batch/v1,batch/v2alpha1,extensions/v1beta1,apps/v1alpha1,federation/v1beta1,policy/v1alpha1,rbac.authorization.k8s.io/v1alpha1,certificates/v1alpha1"} KUBE_TEST_API_VERSIONS=${KUBE_TEST_API_VERSIONS:-"v1,apps/v1alpha1,authentication.k8s.io/v1beta1,authorization.k8s.io/v1beta1,autoscaling/v1,batch/v1,batch/v2alpha1,certificates/v1alpha1,extensions/v1beta1,federation/v1beta1,policy/v1alpha1,rbac.authorization.k8s.io/v1alpha1"}
# once we have multiple group supports # once we have multiple group supports
# Create a junit-style XML test report in this directory if set. # Create a junit-style XML test report in this directory if set.
KUBE_JUNIT_REPORT_DIR=${KUBE_JUNIT_REPORT_DIR:-} KUBE_JUNIT_REPORT_DIR=${KUBE_JUNIT_REPORT_DIR:-}
......
...@@ -39,7 +39,7 @@ setgen=$(kube::util::find-binary "set-gen") ...@@ -39,7 +39,7 @@ setgen=$(kube::util::find-binary "set-gen")
# update- and verify- scripts. # update- and verify- scripts.
${clientgen} "$@" ${clientgen} "$@"
${clientgen} -t "$@" ${clientgen} -t "$@"
${clientgen} --clientset-name="release_1_4" --input="api/v1,extensions/v1beta1,autoscaling/v1,batch/v1" ${clientgen} --clientset-name="release_1_4" --input="api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1"
# Clientgen for federation clientset. # Clientgen for federation clientset.
${clientgen} --clientset-name=federation_internalclientset --clientset-path=k8s.io/kubernetes/federation/client/clientset_generated --input="../../federation/apis/federation/","api/","extensions/" --included-types-overrides="api/Service,api/Namespace,extensions/ReplicaSet,api/Secret" "$@" ${clientgen} --clientset-name=federation_internalclientset --clientset-path=k8s.io/kubernetes/federation/client/clientset_generated --input="../../federation/apis/federation/","api/","extensions/" --included-types-overrides="api/Service,api/Namespace,extensions/ReplicaSet,api/Secret" "$@"
${clientgen} --clientset-name=federation_release_1_4 --clientset-path=k8s.io/kubernetes/federation/client/clientset_generated --input="../../federation/apis/federation/v1beta1","api/v1","extensions/v1beta1" --included-types-overrides="api/v1/Service,api/v1/Namespace,extensions/v1beta1/ReplicaSet,api/v1/Secret" "$@" ${clientgen} --clientset-name=federation_release_1_4 --clientset-path=k8s.io/kubernetes/federation/client/clientset_generated --input="../../federation/apis/federation/v1beta1","api/v1","extensions/v1beta1" --included-types-overrides="api/v1/Service,api/v1/Namespace,extensions/v1beta1/ReplicaSet,api/v1/Secret" "$@"
......
...@@ -74,7 +74,7 @@ APISERVER_PID=$! ...@@ -74,7 +74,7 @@ APISERVER_PID=$!
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver: " kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/healthz" "apiserver: "
SWAGGER_API_PATH="http://127.0.0.1:${API_PORT}/swaggerapi/" SWAGGER_API_PATH="http://127.0.0.1:${API_PORT}/swaggerapi/"
DEFAULT_GROUP_VERSIONS="v1 authentication.k8s.io/v1beta1 autoscaling/v1 batch/v1 batch/v2alpha1 extensions/v1beta1 apps/v1alpha1 policy/v1alpha1 rbac.authorization.k8s.io/v1alpha1 certificates/v1alpha1" DEFAULT_GROUP_VERSIONS="v1 apps/v1alpha1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1beta1 autoscaling/v1 batch/v1 batch/v2alpha1 extensions/v1beta1 certificates/v1alpha1 policy/v1alpha1 rbac.authorization.k8s.io/v1alpha1"
VERSIONS=${VERSIONS:-$DEFAULT_GROUP_VERSIONS} VERSIONS=${VERSIONS:-$DEFAULT_GROUP_VERSIONS}
kube::log::status "Updating " ${SWAGGER_ROOT_DIR} kube::log::status "Updating " ${SWAGGER_ROOT_DIR}
......
...@@ -43,6 +43,7 @@ import ( ...@@ -43,6 +43,7 @@ import (
_ "k8s.io/kubernetes/pkg/api/install" _ "k8s.io/kubernetes/pkg/api/install"
_ "k8s.io/kubernetes/pkg/apis/apps/install" _ "k8s.io/kubernetes/pkg/apis/apps/install"
_ "k8s.io/kubernetes/pkg/apis/authentication/install" _ "k8s.io/kubernetes/pkg/apis/authentication/install"
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install" _ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
_ "k8s.io/kubernetes/pkg/apis/batch/install" _ "k8s.io/kubernetes/pkg/apis/batch/install"
_ "k8s.io/kubernetes/pkg/apis/certificates/install" _ "k8s.io/kubernetes/pkg/apis/certificates/install"
......
...@@ -16,4 +16,5 @@ limitations under the License. ...@@ -16,4 +16,5 @@ limitations under the License.
// +k8s:deepcopy-gen=package,register // +k8s:deepcopy-gen=package,register
// +groupName=authorization.k8s.io
package authorization // import "k8s.io/kubernetes/pkg/apis/authorization" package authorization // import "k8s.io/kubernetes/pkg/apis/authorization"
...@@ -17,13 +17,19 @@ limitations under the License. ...@@ -17,13 +17,19 @@ limitations under the License.
package authorization package authorization
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
) )
// +genclient=true
// +nonNamespaced=true
// +noMethods=true
// SubjectAccessReview checks whether or not a user or group can perform an action. Not filling in a // SubjectAccessReview checks whether or not a user or group can perform an action. Not filling in a
// spec.namespace means "in all namespaces". // spec.namespace means "in all namespaces".
type SubjectAccessReview struct { type SubjectAccessReview struct {
unversioned.TypeMeta unversioned.TypeMeta
api.ObjectMeta
// Spec holds information about the request being evaluated // Spec holds information about the request being evaluated
Spec SubjectAccessReviewSpec Spec SubjectAccessReviewSpec
...@@ -37,6 +43,7 @@ type SubjectAccessReview struct { ...@@ -37,6 +43,7 @@ type SubjectAccessReview struct {
// to check whether they can perform an action // to check whether they can perform an action
type SelfSubjectAccessReview struct { type SelfSubjectAccessReview struct {
unversioned.TypeMeta unversioned.TypeMeta
api.ObjectMeta
// Spec holds information about the request being evaluated. // Spec holds information about the request being evaluated.
Spec SelfSubjectAccessReviewSpec Spec SelfSubjectAccessReviewSpec
...@@ -50,6 +57,7 @@ type SelfSubjectAccessReview struct { ...@@ -50,6 +57,7 @@ type SelfSubjectAccessReview struct {
// checking. // checking.
type LocalSubjectAccessReview struct { type LocalSubjectAccessReview struct {
unversioned.TypeMeta unversioned.TypeMeta
api.ObjectMeta
// Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace
// you made the request against. If empty, it is defaulted. // you made the request against. If empty, it is defaulted.
...@@ -103,9 +111,13 @@ type SubjectAccessReviewSpec struct { ...@@ -103,9 +111,13 @@ type SubjectAccessReviewSpec struct {
Groups []string Groups []string
// Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer
// it needs a reflection here. // it needs a reflection here.
Extra map[string][]string Extra map[string]ExtraValue
} }
// ExtraValue masks the value so protobuf can generate
// +protobuf.nullable=true
type ExtraValue []string
// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAttributes // SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAttributes
// and NonResourceAttributes must be set // and NonResourceAttributes must be set
type SelfSubjectAccessReviewSpec struct { type SelfSubjectAccessReviewSpec struct {
...@@ -121,4 +133,8 @@ type SubjectAccessReviewStatus struct { ...@@ -121,4 +133,8 @@ type SubjectAccessReviewStatus struct {
Allowed bool Allowed bool
// Reason is optional. It indicates why a request was allowed or denied. // Reason is optional. It indicates why a request was allowed or denied.
Reason string Reason string
// EvaluationError is an indication that some error occurred during the authorization check.
// It is entirely possible to get an error and be able to continue determine authorization status in spite of it.
// For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.
EvaluationError string
} }
...@@ -17,4 +17,5 @@ limitations under the License. ...@@ -17,4 +17,5 @@ limitations under the License.
// +k8s:deepcopy-gen=package,register // +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/authorization // +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/authorization
// +groupName=authorization.k8s.io
package v1beta1 // import "k8s.io/kubernetes/pkg/apis/authorization/v1beta1" package v1beta1 // import "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
/*
Copyright 2016 The Kubernetes Authors.
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.
*/
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
syntax = 'proto2';
package k8s.io.kubernetes.pkg.apis.authorization.v1beta1;
import "k8s.io/kubernetes/pkg/api/resource/generated.proto";
import "k8s.io/kubernetes/pkg/api/unversioned/generated.proto";
import "k8s.io/kubernetes/pkg/api/v1/generated.proto";
import "k8s.io/kubernetes/pkg/runtime/generated.proto";
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "v1beta1";
// ExtraValue masks the value so protobuf can generate
// +protobuf.nullable=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
message ExtraValue {
// items, if empty, will result in an empty slice
repeated string items = 1;
}
// LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace.
// Having a namespace scoped resource makes it much easier to grant namespace scoped policy that includes permissions
// checking.
message LocalSubjectAccessReview {
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace
// you made the request against. If empty, it is defaulted.
optional SubjectAccessReviewSpec spec = 2;
// Status is filled in by the server and indicates whether the request is allowed or not
optional SubjectAccessReviewStatus status = 3;
}
// NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface
message NonResourceAttributes {
// Path is the URL path of the request
optional string path = 1;
// Verb is the standard HTTP verb
optional string verb = 2;
}
// ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface
message ResourceAttributes {
// Namespace is the namespace of the action being requested. Currently, there is no distinction between no namespace and all namespaces
// "" (empty) is defaulted for LocalSubjectAccessReviews
// "" (empty) is empty for cluster-scoped resources
// "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview
optional string namespace = 1;
// Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.
optional string verb = 2;
// Group is the API Group of the Resource. "*" means all.
optional string group = 3;
// Version is the API Version of the Resource. "*" means all.
optional string version = 4;
// Resource is one of the existing resource types. "*" means all.
optional string resource = 5;
// Subresource is one of the existing resource types. "" means none.
optional string subresource = 6;
// Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all.
optional string name = 7;
}
// SelfSubjectAccessReview checks whether or the current user can perform an action. Not filling in a
// spec.namespace means "in all namespaces". Self is a special case, because users should always be able
// to check whether they can perform an action
message SelfSubjectAccessReview {
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Spec holds information about the request being evaluated. user and groups must be empty
optional SelfSubjectAccessReviewSpec spec = 2;
// Status is filled in by the server and indicates whether the request is allowed or not
optional SubjectAccessReviewStatus status = 3;
}
// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes
// and NonResourceAuthorizationAttributes must be set
message SelfSubjectAccessReviewSpec {
// ResourceAuthorizationAttributes describes information for a resource access request
optional ResourceAttributes resourceAttributes = 1;
// NonResourceAttributes describes information for a non-resource access request
optional NonResourceAttributes nonResourceAttributes = 2;
}
// SubjectAccessReview checks whether or not a user or group can perform an action.
message SubjectAccessReview {
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Spec holds information about the request being evaluated
optional SubjectAccessReviewSpec spec = 2;
// Status is filled in by the server and indicates whether the request is allowed or not
optional SubjectAccessReviewStatus status = 3;
}
// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes
// and NonResourceAuthorizationAttributes must be set
message SubjectAccessReviewSpec {
// ResourceAuthorizationAttributes describes information for a resource access request
optional ResourceAttributes resourceAttributes = 1;
// NonResourceAttributes describes information for a non-resource access request
optional NonResourceAttributes nonResourceAttributes = 2;
// User is the user you're testing for.
// If you specify "User" but not "Group", then is it interpreted as "What if User were not a member of any groups
optional string verb = 3;
// Groups is the groups you're testing for.
repeated string group = 4;
// Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer
// it needs a reflection here.
map<string, ExtraValue> extra = 5;
}
// SubjectAccessReviewStatus
message SubjectAccessReviewStatus {
// Allowed is required. True if the action would be allowed, false otherwise.
optional bool allowed = 1;
// Reason is optional. It indicates why a request was allowed or denied.
optional string reason = 2;
// EvaluationError is an indication that some error occurred during the authorization check.
// It is entirely possible to get an error and be able to continue determine authorization status in spite of it.
// For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.
optional string evaluationError = 3;
}
...@@ -18,7 +18,9 @@ package v1beta1 ...@@ -18,7 +18,9 @@ package v1beta1
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
versionedwatch "k8s.io/kubernetes/pkg/watch/versioned"
) )
// GroupName is the group name use in this package // GroupName is the group name use in this package
...@@ -37,10 +39,15 @@ func AddToScheme(scheme *runtime.Scheme) { ...@@ -37,10 +39,15 @@ func AddToScheme(scheme *runtime.Scheme) {
// Adds the list of known types to api.Scheme. // Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) { func addKnownTypes(scheme *runtime.Scheme) {
scheme.AddKnownTypes(SchemeGroupVersion, scheme.AddKnownTypes(SchemeGroupVersion,
&v1.ListOptions{},
&v1.DeleteOptions{},
&SelfSubjectAccessReview{}, &SelfSubjectAccessReview{},
&SubjectAccessReview{}, &SubjectAccessReview{},
&LocalSubjectAccessReview{}, &LocalSubjectAccessReview{},
) )
versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion)
} }
func (obj *LocalSubjectAccessReview) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } func (obj *LocalSubjectAccessReview) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
......
...@@ -17,18 +17,26 @@ limitations under the License. ...@@ -17,18 +17,26 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"fmt"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
) )
// +genclient=true
// +nonNamespaced=true
// +noMethods=true
// SubjectAccessReview checks whether or not a user or group can perform an action. // SubjectAccessReview checks whether or not a user or group can perform an action.
type SubjectAccessReview struct { type SubjectAccessReview struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec holds information about the request being evaluated // Spec holds information about the request being evaluated
Spec SubjectAccessReviewSpec `json:"spec"` Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// Status is filled in by the server and indicates whether the request is allowed or not // Status is filled in by the server and indicates whether the request is allowed or not
Status SubjectAccessReviewStatus `json:"status,omitempty"` Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
} }
// SelfSubjectAccessReview checks whether or the current user can perform an action. Not filling in a // SelfSubjectAccessReview checks whether or the current user can perform an action. Not filling in a
...@@ -36,12 +44,13 @@ type SubjectAccessReview struct { ...@@ -36,12 +44,13 @@ type SubjectAccessReview struct {
// to check whether they can perform an action // to check whether they can perform an action
type SelfSubjectAccessReview struct { type SelfSubjectAccessReview struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec holds information about the request being evaluated. user and groups must be empty // Spec holds information about the request being evaluated. user and groups must be empty
Spec SelfSubjectAccessReviewSpec `json:"spec"` Spec SelfSubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// Status is filled in by the server and indicates whether the request is allowed or not // Status is filled in by the server and indicates whether the request is allowed or not
Status SubjectAccessReviewStatus `json:"status,omitempty"` Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
} }
// LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace. // LocalSubjectAccessReview checks whether or not a user or group can perform an action in a given namespace.
...@@ -49,13 +58,14 @@ type SelfSubjectAccessReview struct { ...@@ -49,13 +58,14 @@ type SelfSubjectAccessReview struct {
// checking. // checking.
type LocalSubjectAccessReview struct { type LocalSubjectAccessReview struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace // Spec holds information about the request being evaluated. spec.namespace must be equal to the namespace
// you made the request against. If empty, it is defaulted. // you made the request against. If empty, it is defaulted.
Spec SubjectAccessReviewSpec `json:"spec"` Spec SubjectAccessReviewSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
// Status is filled in by the server and indicates whether the request is allowed or not // Status is filled in by the server and indicates whether the request is allowed or not
Status SubjectAccessReviewStatus `json:"status,omitempty"` Status SubjectAccessReviewStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
} }
// ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface // ResourceAttributes includes the authorization attributes available for resource requests to the Authorizer interface
...@@ -64,60 +74,73 @@ type ResourceAttributes struct { ...@@ -64,60 +74,73 @@ type ResourceAttributes struct {
// "" (empty) is defaulted for LocalSubjectAccessReviews // "" (empty) is defaulted for LocalSubjectAccessReviews
// "" (empty) is empty for cluster-scoped resources // "" (empty) is empty for cluster-scoped resources
// "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview // "" (empty) means "all" for namespace scoped resources from a SubjectAccessReview or SelfSubjectAccessReview
Namespace string `json:"namespace,omitempty"` Namespace string `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"`
// Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all. // Verb is a kubernetes resource API verb, like: get, list, watch, create, update, delete, proxy. "*" means all.
Verb string `json:"verb,omitempty"` Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"`
// Group is the API Group of the Resource. "*" means all. // Group is the API Group of the Resource. "*" means all.
Group string `json:"group,omitempty"` Group string `json:"group,omitempty" protobuf:"bytes,3,opt,name=group"`
// Version is the API Version of the Resource. "*" means all. // Version is the API Version of the Resource. "*" means all.
Version string `json:"version,omitempty"` Version string `json:"version,omitempty" protobuf:"bytes,4,opt,name=version"`
// Resource is one of the existing resource types. "*" means all. // Resource is one of the existing resource types. "*" means all.
Resource string `json:"resource,omitempty"` Resource string `json:"resource,omitempty" protobuf:"bytes,5,opt,name=resource"`
// Subresource is one of the existing resource types. "" means none. // Subresource is one of the existing resource types. "" means none.
Subresource string `json:"subresource,omitempty"` Subresource string `json:"subresource,omitempty" protobuf:"bytes,6,opt,name=subresource"`
// Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all. // Name is the name of the resource being requested for a "get" or deleted for a "delete". "" (empty) means all.
Name string `json:"name,omitempty"` Name string `json:"name,omitempty" protobuf:"bytes,7,opt,name=name"`
} }
// NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface // NonResourceAttributes includes the authorization attributes available for non-resource requests to the Authorizer interface
type NonResourceAttributes struct { type NonResourceAttributes struct {
// Path is the URL path of the request // Path is the URL path of the request
Path string `json:"path,omitempty"` Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"`
// Verb is the standard HTTP verb // Verb is the standard HTTP verb
Verb string `json:"verb,omitempty"` Verb string `json:"verb,omitempty" protobuf:"bytes,2,opt,name=verb"`
} }
// SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes // SubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes
// and NonResourceAuthorizationAttributes must be set // and NonResourceAuthorizationAttributes must be set
type SubjectAccessReviewSpec struct { type SubjectAccessReviewSpec struct {
// ResourceAuthorizationAttributes describes information for a resource access request // ResourceAuthorizationAttributes describes information for a resource access request
ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty"` ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"`
// NonResourceAttributes describes information for a non-resource access request // NonResourceAttributes describes information for a non-resource access request
NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty"` NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"`
// User is the user you're testing for. // User is the user you're testing for.
// If you specify "User" but not "Group", then is it interpreted as "What if User were not a member of any groups // If you specify "User" but not "Group", then is it interpreted as "What if User were not a member of any groups
User string `json:"user,omitempty"` User string `json:"user,omitempty" protobuf:"bytes,3,opt,name=verb"`
// Groups is the groups you're testing for. // Groups is the groups you're testing for.
Groups []string `json:"group,omitempty"` Groups []string `json:"group,omitempty" protobuf:"bytes,4,rep,name=group"`
// Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer // Extra corresponds to the user.Info.GetExtra() method from the authenticator. Since that is input to the authorizer
// it needs a reflection here. // it needs a reflection here.
Extra map[string][]string `json:"extra,omitempty"` Extra map[string]ExtraValue `json:"extra,omitempty" protobuf:"bytes,5,rep,name=extra"`
}
// ExtraValue masks the value so protobuf can generate
// +protobuf.nullable=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
type ExtraValue []string
func (t ExtraValue) String() string {
return fmt.Sprintf("%v", []string(t))
} }
// SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes // SelfSubjectAccessReviewSpec is a description of the access request. Exactly one of ResourceAuthorizationAttributes
// and NonResourceAuthorizationAttributes must be set // and NonResourceAuthorizationAttributes must be set
type SelfSubjectAccessReviewSpec struct { type SelfSubjectAccessReviewSpec struct {
// ResourceAuthorizationAttributes describes information for a resource access request // ResourceAuthorizationAttributes describes information for a resource access request
ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty"` ResourceAttributes *ResourceAttributes `json:"resourceAttributes,omitempty" protobuf:"bytes,1,opt,name=resourceAttributes"`
// NonResourceAttributes describes information for a non-resource access request // NonResourceAttributes describes information for a non-resource access request
NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty"` NonResourceAttributes *NonResourceAttributes `json:"nonResourceAttributes,omitempty" protobuf:"bytes,2,opt,name=nonResourceAttributes"`
} }
// SubjectAccessReviewStatus // SubjectAccessReviewStatus
type SubjectAccessReviewStatus struct { type SubjectAccessReviewStatus struct {
// Allowed is required. True if the action would be allowed, false otherwise. // Allowed is required. True if the action would be allowed, false otherwise.
Allowed bool `json:"allowed"` Allowed bool `json:"allowed" protobuf:"varint,1,opt,name=allowed"`
// Reason is optional. It indicates why a request was allowed or denied. // Reason is optional. It indicates why a request was allowed or denied.
Reason string `json:"reason,omitempty"` Reason string `json:"reason,omitempty" protobuf:"bytes,2,opt,name=reason"`
// EvaluationError is an indication that some error occurred during the authorization check.
// It is entirely possible to get an error and be able to continue determine authorization status in spite of it.
// For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.
EvaluationError string `json:"evaluationError,omitempty" protobuf:"bytes,3,opt,name=evaluationError"`
} }
...@@ -106,9 +106,10 @@ func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string { ...@@ -106,9 +106,10 @@ func (SubjectAccessReviewSpec) SwaggerDoc() map[string]string {
} }
var map_SubjectAccessReviewStatus = map[string]string{ var map_SubjectAccessReviewStatus = map[string]string{
"": "SubjectAccessReviewStatus", "": "SubjectAccessReviewStatus",
"allowed": "Allowed is required. True if the action would be allowed, false otherwise.", "allowed": "Allowed is required. True if the action would be allowed, false otherwise.",
"reason": "Reason is optional. It indicates why a request was allowed or denied.", "reason": "Reason is optional. It indicates why a request was allowed or denied.",
"evaluationError": "EvaluationError is an indication that some error occurred during the authorization check. It is entirely possible to get an error and be able to continue determine authorization status in spite of it. For instance, RBAC can be missing a role, but enough roles are still present and bound to reason about the request.",
} }
func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string { func (SubjectAccessReviewStatus) SwaggerDoc() map[string]string {
......
...@@ -54,6 +54,10 @@ func autoConvert_v1beta1_LocalSubjectAccessReview_To_authorization_LocalSubjectA ...@@ -54,6 +54,10 @@ func autoConvert_v1beta1_LocalSubjectAccessReview_To_authorization_LocalSubjectA
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -71,6 +75,10 @@ func autoConvert_authorization_LocalSubjectAccessReview_To_v1beta1_LocalSubjectA ...@@ -71,6 +75,10 @@ func autoConvert_authorization_LocalSubjectAccessReview_To_v1beta1_LocalSubjectA
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -138,6 +146,10 @@ func autoConvert_v1beta1_SelfSubjectAccessReview_To_authorization_SelfSubjectAcc ...@@ -138,6 +146,10 @@ func autoConvert_v1beta1_SelfSubjectAccessReview_To_authorization_SelfSubjectAcc
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_v1beta1_SelfSubjectAccessReviewSpec_To_authorization_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_v1beta1_SelfSubjectAccessReviewSpec_To_authorization_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -155,6 +167,10 @@ func autoConvert_authorization_SelfSubjectAccessReview_To_v1beta1_SelfSubjectAcc ...@@ -155,6 +167,10 @@ func autoConvert_authorization_SelfSubjectAccessReview_To_v1beta1_SelfSubjectAcc
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_authorization_SelfSubjectAccessReviewSpec_To_v1beta1_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_authorization_SelfSubjectAccessReviewSpec_To_v1beta1_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -224,6 +240,10 @@ func autoConvert_v1beta1_SubjectAccessReview_To_authorization_SubjectAccessRevie ...@@ -224,6 +240,10 @@ func autoConvert_v1beta1_SubjectAccessReview_To_authorization_SubjectAccessRevie
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -241,6 +261,10 @@ func autoConvert_authorization_SubjectAccessReview_To_v1beta1_SubjectAccessRevie ...@@ -241,6 +261,10 @@ func autoConvert_authorization_SubjectAccessReview_To_v1beta1_SubjectAccessRevie
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err return err
} }
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil { if err := Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, s); err != nil {
return err return err
} }
...@@ -275,7 +299,20 @@ func autoConvert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessR ...@@ -275,7 +299,20 @@ func autoConvert_v1beta1_SubjectAccessReviewSpec_To_authorization_SubjectAccessR
} }
out.User = in.User out.User = in.User
out.Groups = in.Groups out.Groups = in.Groups
out.Extra = in.Extra if in.Extra != nil {
in, out := &in.Extra, &out.Extra
*out = make(map[string]authorization.ExtraValue, len(*in))
for key, val := range *in {
newVal := new(authorization.ExtraValue)
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&val, newVal, 0); err != nil {
return err
}
(*out)[key] = *newVal
}
} else {
out.Extra = nil
}
return nil return nil
} }
...@@ -304,7 +341,20 @@ func autoConvert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessR ...@@ -304,7 +341,20 @@ func autoConvert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessR
} }
out.User = in.User out.User = in.User
out.Groups = in.Groups out.Groups = in.Groups
out.Extra = in.Extra if in.Extra != nil {
in, out := &in.Extra, &out.Extra
*out = make(map[string]ExtraValue, len(*in))
for key, val := range *in {
newVal := new(ExtraValue)
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&val, newVal, 0); err != nil {
return err
}
(*out)[key] = *newVal
}
} else {
out.Extra = nil
}
return nil return nil
} }
...@@ -315,6 +365,7 @@ func Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessRevie ...@@ -315,6 +365,7 @@ func Convert_authorization_SubjectAccessReviewSpec_To_v1beta1_SubjectAccessRevie
func autoConvert_v1beta1_SubjectAccessReviewStatus_To_authorization_SubjectAccessReviewStatus(in *SubjectAccessReviewStatus, out *authorization.SubjectAccessReviewStatus, s conversion.Scope) error { func autoConvert_v1beta1_SubjectAccessReviewStatus_To_authorization_SubjectAccessReviewStatus(in *SubjectAccessReviewStatus, out *authorization.SubjectAccessReviewStatus, s conversion.Scope) error {
out.Allowed = in.Allowed out.Allowed = in.Allowed
out.Reason = in.Reason out.Reason = in.Reason
out.EvaluationError = in.EvaluationError
return nil return nil
} }
...@@ -325,6 +376,7 @@ func Convert_v1beta1_SubjectAccessReviewStatus_To_authorization_SubjectAccessRev ...@@ -325,6 +376,7 @@ func Convert_v1beta1_SubjectAccessReviewStatus_To_authorization_SubjectAccessRev
func autoConvert_authorization_SubjectAccessReviewStatus_To_v1beta1_SubjectAccessReviewStatus(in *authorization.SubjectAccessReviewStatus, out *SubjectAccessReviewStatus, s conversion.Scope) error { func autoConvert_authorization_SubjectAccessReviewStatus_To_v1beta1_SubjectAccessReviewStatus(in *authorization.SubjectAccessReviewStatus, out *SubjectAccessReviewStatus, s conversion.Scope) error {
out.Allowed = in.Allowed out.Allowed = in.Allowed
out.Reason = in.Reason out.Reason = in.Reason
out.EvaluationError = in.EvaluationError
return nil return nil
} }
......
...@@ -22,6 +22,7 @@ package v1beta1 ...@@ -22,6 +22,7 @@ package v1beta1
import ( import (
api "k8s.io/kubernetes/pkg/api" api "k8s.io/kubernetes/pkg/api"
v1 "k8s.io/kubernetes/pkg/api/v1"
conversion "k8s.io/kubernetes/pkg/conversion" conversion "k8s.io/kubernetes/pkg/conversion"
reflect "reflect" reflect "reflect"
) )
...@@ -47,6 +48,9 @@ func DeepCopy_v1beta1_LocalSubjectAccessReview(in interface{}, out interface{}, ...@@ -47,6 +48,9 @@ func DeepCopy_v1beta1_LocalSubjectAccessReview(in interface{}, out interface{},
in := in.(*LocalSubjectAccessReview) in := in.(*LocalSubjectAccessReview)
out := out.(*LocalSubjectAccessReview) out := out.(*LocalSubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -85,6 +89,9 @@ func DeepCopy_v1beta1_SelfSubjectAccessReview(in interface{}, out interface{}, c ...@@ -85,6 +89,9 @@ func DeepCopy_v1beta1_SelfSubjectAccessReview(in interface{}, out interface{}, c
in := in.(*SelfSubjectAccessReview) in := in.(*SelfSubjectAccessReview)
out := out.(*SelfSubjectAccessReview) out := out.(*SelfSubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_v1beta1_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_v1beta1_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -120,6 +127,9 @@ func DeepCopy_v1beta1_SubjectAccessReview(in interface{}, out interface{}, c *co ...@@ -120,6 +127,9 @@ func DeepCopy_v1beta1_SubjectAccessReview(in interface{}, out interface{}, c *co
in := in.(*SubjectAccessReview) in := in.(*SubjectAccessReview)
out := out.(*SubjectAccessReview) out := out.(*SubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_v1beta1_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -156,12 +166,12 @@ func DeepCopy_v1beta1_SubjectAccessReviewSpec(in interface{}, out interface{}, c ...@@ -156,12 +166,12 @@ func DeepCopy_v1beta1_SubjectAccessReviewSpec(in interface{}, out interface{}, c
} }
if in.Extra != nil { if in.Extra != nil {
in, out := &in.Extra, &out.Extra in, out := &in.Extra, &out.Extra
*out = make(map[string][]string) *out = make(map[string]ExtraValue)
for key, val := range *in { for key, val := range *in {
if newVal, err := c.DeepCopy(&val); err != nil { if newVal, err := c.DeepCopy(&val); err != nil {
return err return err
} else { } else {
(*out)[key] = *newVal.(*[]string) (*out)[key] = *newVal.(*ExtraValue)
} }
} }
} else { } else {
...@@ -177,6 +187,7 @@ func DeepCopy_v1beta1_SubjectAccessReviewStatus(in interface{}, out interface{}, ...@@ -177,6 +187,7 @@ func DeepCopy_v1beta1_SubjectAccessReviewStatus(in interface{}, out interface{},
out := out.(*SubjectAccessReviewStatus) out := out.(*SubjectAccessReviewStatus)
out.Allowed = in.Allowed out.Allowed = in.Allowed
out.Reason = in.Reason out.Reason = in.Reason
out.EvaluationError = in.EvaluationError
return nil return nil
} }
} }
...@@ -17,6 +17,7 @@ limitations under the License. ...@@ -17,6 +17,7 @@ limitations under the License.
package validation package validation
import ( import (
"k8s.io/kubernetes/pkg/api"
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization" authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/util/validation/field" "k8s.io/kubernetes/pkg/util/validation/field"
) )
...@@ -50,15 +51,24 @@ func ValidateSelfSubjectAccessReviewSpec(spec authorizationapi.SelfSubjectAccess ...@@ -50,15 +51,24 @@ func ValidateSelfSubjectAccessReviewSpec(spec authorizationapi.SelfSubjectAccess
func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList { func ValidateSubjectAccessReview(sar *authorizationapi.SubjectAccessReview) field.ErrorList {
allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec"))
if !api.Semantic.DeepEqual(api.ObjectMeta{}, sar.ObjectMeta) {
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
}
return allErrs return allErrs
} }
func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList { func ValidateSelfSubjectAccessReview(sar *authorizationapi.SelfSubjectAccessReview) field.ErrorList {
allErrs := ValidateSelfSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) allErrs := ValidateSelfSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec"))
if !api.Semantic.DeepEqual(api.ObjectMeta{}, sar.ObjectMeta) {
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
}
return allErrs return allErrs
} }
func ValidateLocalSubjectAccessReview(sar *authorizationapi.LocalSubjectAccessReview) field.ErrorList { func ValidateLocalSubjectAccessReview(sar *authorizationapi.LocalSubjectAccessReview) field.ErrorList {
allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec")) allErrs := ValidateSubjectAccessReviewSpec(sar.Spec, field.NewPath("spec"))
if !api.Semantic.DeepEqual(api.ObjectMeta{}, sar.ObjectMeta) {
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata"), sar.ObjectMeta, `must be empty`))
}
return allErrs return allErrs
} }
...@@ -47,6 +47,9 @@ func DeepCopy_authorization_LocalSubjectAccessReview(in interface{}, out interfa ...@@ -47,6 +47,9 @@ func DeepCopy_authorization_LocalSubjectAccessReview(in interface{}, out interfa
in := in.(*LocalSubjectAccessReview) in := in.(*LocalSubjectAccessReview)
out := out.(*LocalSubjectAccessReview) out := out.(*LocalSubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -85,6 +88,9 @@ func DeepCopy_authorization_SelfSubjectAccessReview(in interface{}, out interfac ...@@ -85,6 +88,9 @@ func DeepCopy_authorization_SelfSubjectAccessReview(in interface{}, out interfac
in := in.(*SelfSubjectAccessReview) in := in.(*SelfSubjectAccessReview)
out := out.(*SelfSubjectAccessReview) out := out.(*SelfSubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_authorization_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_authorization_SelfSubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -120,6 +126,9 @@ func DeepCopy_authorization_SubjectAccessReview(in interface{}, out interface{}, ...@@ -120,6 +126,9 @@ func DeepCopy_authorization_SubjectAccessReview(in interface{}, out interface{},
in := in.(*SubjectAccessReview) in := in.(*SubjectAccessReview)
out := out.(*SubjectAccessReview) out := out.(*SubjectAccessReview)
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if err := DeepCopy_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil { if err := DeepCopy_authorization_SubjectAccessReviewSpec(&in.Spec, &out.Spec, c); err != nil {
return err return err
} }
...@@ -156,12 +165,12 @@ func DeepCopy_authorization_SubjectAccessReviewSpec(in interface{}, out interfac ...@@ -156,12 +165,12 @@ func DeepCopy_authorization_SubjectAccessReviewSpec(in interface{}, out interfac
} }
if in.Extra != nil { if in.Extra != nil {
in, out := &in.Extra, &out.Extra in, out := &in.Extra, &out.Extra
*out = make(map[string][]string) *out = make(map[string]ExtraValue)
for key, val := range *in { for key, val := range *in {
if newVal, err := c.DeepCopy(&val); err != nil { if newVal, err := c.DeepCopy(&val); err != nil {
return err return err
} else { } else {
(*out)[key] = *newVal.(*[]string) (*out)[key] = *newVal.(*ExtraValue)
} }
} }
} else { } else {
...@@ -177,6 +186,7 @@ func DeepCopy_authorization_SubjectAccessReviewStatus(in interface{}, out interf ...@@ -177,6 +186,7 @@ func DeepCopy_authorization_SubjectAccessReviewStatus(in interface{}, out interf
out := out.(*SubjectAccessReviewStatus) out := out.(*SubjectAccessReviewStatus)
out.Allowed = in.Allowed out.Allowed = in.Allowed
out.Reason = in.Reason out.Reason = in.Reason
out.EvaluationError = in.EvaluationError
return nil return nil
} }
} }
...@@ -19,6 +19,7 @@ package internalclientset ...@@ -19,6 +19,7 @@ package internalclientset
import ( import (
"github.com/golang/glog" "github.com/golang/glog"
unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned" unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned"
unversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned" unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned"
unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned" unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned"
unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned" unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned"
...@@ -33,12 +34,13 @@ import ( ...@@ -33,12 +34,13 @@ import (
type Interface interface { type Interface interface {
Discovery() discovery.DiscoveryInterface Discovery() discovery.DiscoveryInterface
Core() unversionedcore.CoreInterface Core() unversionedcore.CoreInterface
Extensions() unversionedextensions.ExtensionsInterface
Autoscaling() unversionedautoscaling.AutoscalingInterface
Authentication() unversionedauthentication.AuthenticationInterface Authentication() unversionedauthentication.AuthenticationInterface
Authorization() unversionedauthorization.AuthorizationInterface
Autoscaling() unversionedautoscaling.AutoscalingInterface
Batch() unversionedbatch.BatchInterface Batch() unversionedbatch.BatchInterface
Rbac() unversionedrbac.RbacInterface
Certificates() unversionedcertificates.CertificatesInterface Certificates() unversionedcertificates.CertificatesInterface
Extensions() unversionedextensions.ExtensionsInterface
Rbac() unversionedrbac.RbacInterface
} }
// Clientset contains the clients for groups. Each group has exactly one // Clientset contains the clients for groups. Each group has exactly one
...@@ -46,12 +48,13 @@ type Interface interface { ...@@ -46,12 +48,13 @@ type Interface interface {
type Clientset struct { type Clientset struct {
*discovery.DiscoveryClient *discovery.DiscoveryClient
*unversionedcore.CoreClient *unversionedcore.CoreClient
*unversionedextensions.ExtensionsClient
*unversionedautoscaling.AutoscalingClient
*unversionedauthentication.AuthenticationClient *unversionedauthentication.AuthenticationClient
*unversionedauthorization.AuthorizationClient
*unversionedautoscaling.AutoscalingClient
*unversionedbatch.BatchClient *unversionedbatch.BatchClient
*unversionedrbac.RbacClient
*unversionedcertificates.CertificatesClient *unversionedcertificates.CertificatesClient
*unversionedextensions.ExtensionsClient
*unversionedrbac.RbacClient
} }
// Core retrieves the CoreClient // Core retrieves the CoreClient
...@@ -62,28 +65,28 @@ func (c *Clientset) Core() unversionedcore.CoreInterface { ...@@ -62,28 +65,28 @@ func (c *Clientset) Core() unversionedcore.CoreInterface {
return c.CoreClient return c.CoreClient
} }
// Extensions retrieves the ExtensionsClient // Authentication retrieves the AuthenticationClient
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface { func (c *Clientset) Authentication() unversionedauthentication.AuthenticationInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.ExtensionsClient return c.AuthenticationClient
} }
// Autoscaling retrieves the AutoscalingClient // Authorization retrieves the AuthorizationClient
func (c *Clientset) Autoscaling() unversionedautoscaling.AutoscalingInterface { func (c *Clientset) Authorization() unversionedauthorization.AuthorizationInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.AutoscalingClient return c.AuthorizationClient
} }
// Authentication retrieves the AuthenticationClient // Autoscaling retrieves the AutoscalingClient
func (c *Clientset) Authentication() unversionedauthentication.AuthenticationInterface { func (c *Clientset) Autoscaling() unversionedautoscaling.AutoscalingInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.AuthenticationClient return c.AutoscalingClient
} }
// Batch retrieves the BatchClient // Batch retrieves the BatchClient
...@@ -94,20 +97,28 @@ func (c *Clientset) Batch() unversionedbatch.BatchInterface { ...@@ -94,20 +97,28 @@ func (c *Clientset) Batch() unversionedbatch.BatchInterface {
return c.BatchClient return c.BatchClient
} }
// Rbac retrieves the RbacClient // Certificates retrieves the CertificatesClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface { func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.RbacClient return c.CertificatesClient
} }
// Certificates retrieves the CertificatesClient // Extensions retrieves the ExtensionsClient
func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface { func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.CertificatesClient return c.ExtensionsClient
}
// Rbac retrieves the RbacClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface {
if c == nil {
return nil
}
return c.RbacClient
} }
// Discovery retrieves the DiscoveryClient // Discovery retrieves the DiscoveryClient
...@@ -127,15 +138,15 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -127,15 +138,15 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.ExtensionsClient, err = unversionedextensions.NewForConfig(&configShallowCopy) clientset.AuthenticationClient, err = unversionedauthentication.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.AutoscalingClient, err = unversionedautoscaling.NewForConfig(&configShallowCopy) clientset.AuthorizationClient, err = unversionedauthorization.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.AuthenticationClient, err = unversionedauthentication.NewForConfig(&configShallowCopy) clientset.AutoscalingClient, err = unversionedautoscaling.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -143,11 +154,15 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -143,11 +154,15 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.RbacClient, err = unversionedrbac.NewForConfig(&configShallowCopy) clientset.CertificatesClient, err = unversionedcertificates.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.CertificatesClient, err = unversionedcertificates.NewForConfig(&configShallowCopy) clientset.ExtensionsClient, err = unversionedextensions.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
clientset.RbacClient, err = unversionedrbac.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -165,12 +180,13 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -165,12 +180,13 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
func NewForConfigOrDie(c *restclient.Config) *Clientset { func NewForConfigOrDie(c *restclient.Config) *Clientset {
var clientset Clientset var clientset Clientset
clientset.CoreClient = unversionedcore.NewForConfigOrDie(c) clientset.CoreClient = unversionedcore.NewForConfigOrDie(c)
clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c)
clientset.AutoscalingClient = unversionedautoscaling.NewForConfigOrDie(c)
clientset.AuthenticationClient = unversionedauthentication.NewForConfigOrDie(c) clientset.AuthenticationClient = unversionedauthentication.NewForConfigOrDie(c)
clientset.AuthorizationClient = unversionedauthorization.NewForConfigOrDie(c)
clientset.AutoscalingClient = unversionedautoscaling.NewForConfigOrDie(c)
clientset.BatchClient = unversionedbatch.NewForConfigOrDie(c) clientset.BatchClient = unversionedbatch.NewForConfigOrDie(c)
clientset.RbacClient = unversionedrbac.NewForConfigOrDie(c)
clientset.CertificatesClient = unversionedcertificates.NewForConfigOrDie(c) clientset.CertificatesClient = unversionedcertificates.NewForConfigOrDie(c)
clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c)
clientset.RbacClient = unversionedrbac.NewForConfigOrDie(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &clientset return &clientset
...@@ -180,12 +196,13 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset { ...@@ -180,12 +196,13 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset {
func New(c *restclient.RESTClient) *Clientset { func New(c *restclient.RESTClient) *Clientset {
var clientset Clientset var clientset Clientset
clientset.CoreClient = unversionedcore.New(c) clientset.CoreClient = unversionedcore.New(c)
clientset.ExtensionsClient = unversionedextensions.New(c)
clientset.AutoscalingClient = unversionedautoscaling.New(c)
clientset.AuthenticationClient = unversionedauthentication.New(c) clientset.AuthenticationClient = unversionedauthentication.New(c)
clientset.AuthorizationClient = unversionedauthorization.New(c)
clientset.AutoscalingClient = unversionedautoscaling.New(c)
clientset.BatchClient = unversionedbatch.New(c) clientset.BatchClient = unversionedbatch.New(c)
clientset.RbacClient = unversionedrbac.New(c)
clientset.CertificatesClient = unversionedcertificates.New(c) clientset.CertificatesClient = unversionedcertificates.New(c)
clientset.ExtensionsClient = unversionedextensions.New(c)
clientset.RbacClient = unversionedrbac.New(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c) clientset.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &clientset return &clientset
......
...@@ -22,6 +22,8 @@ import ( ...@@ -22,6 +22,8 @@ import (
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned" unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned"
fakeunversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned/fake" fakeunversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned/fake"
unversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
fakeunversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned/fake"
unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned" unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned"
fakeunversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned/fake" fakeunversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned/fake"
unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned" unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned"
...@@ -79,9 +81,14 @@ func (c *Clientset) Core() unversionedcore.CoreInterface { ...@@ -79,9 +81,14 @@ func (c *Clientset) Core() unversionedcore.CoreInterface {
return &fakeunversionedcore.FakeCore{Fake: &c.Fake} return &fakeunversionedcore.FakeCore{Fake: &c.Fake}
} }
// Extensions retrieves the ExtensionsClient // Authentication retrieves the AuthenticationClient
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface { func (c *Clientset) Authentication() unversionedauthentication.AuthenticationInterface {
return &fakeunversionedextensions.FakeExtensions{Fake: &c.Fake} return &fakeunversionedauthentication.FakeAuthentication{Fake: &c.Fake}
}
// Authorization retrieves the AuthorizationClient
func (c *Clientset) Authorization() unversionedauthorization.AuthorizationInterface {
return &fakeunversionedauthorization.FakeAuthorization{Fake: &c.Fake}
} }
// Autoscaling retrieves the AutoscalingClient // Autoscaling retrieves the AutoscalingClient
...@@ -89,22 +96,22 @@ func (c *Clientset) Autoscaling() unversionedautoscaling.AutoscalingInterface { ...@@ -89,22 +96,22 @@ func (c *Clientset) Autoscaling() unversionedautoscaling.AutoscalingInterface {
return &fakeunversionedautoscaling.FakeAutoscaling{Fake: &c.Fake} return &fakeunversionedautoscaling.FakeAutoscaling{Fake: &c.Fake}
} }
// Authentication retrieves the AuthenticationClient
func (c *Clientset) Authentication() unversionedauthentication.AuthenticationInterface {
return &fakeunversionedauthentication.FakeAuthentication{Fake: &c.Fake}
}
// Batch retrieves the BatchClient // Batch retrieves the BatchClient
func (c *Clientset) Batch() unversionedbatch.BatchInterface { func (c *Clientset) Batch() unversionedbatch.BatchInterface {
return &fakeunversionedbatch.FakeBatch{Fake: &c.Fake} return &fakeunversionedbatch.FakeBatch{Fake: &c.Fake}
} }
// Rbac retrieves the RbacClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface {
return &fakeunversionedrbac.FakeRbac{Fake: &c.Fake}
}
// Certificates retrieves the CertificatesClient // Certificates retrieves the CertificatesClient
func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface { func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface {
return &fakeunversionedcertificates.FakeCertificates{Fake: &c.Fake} return &fakeunversionedcertificates.FakeCertificates{Fake: &c.Fake}
} }
// Extensions retrieves the ExtensionsClient
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface {
return &fakeunversionedextensions.FakeExtensions{Fake: &c.Fake}
}
// Rbac retrieves the RbacClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface {
return &fakeunversionedrbac.FakeRbac{Fake: &c.Fake}
}
/*
Copyright 2016 The Kubernetes Authors.
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 (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
)
type AuthorizationInterface interface {
GetRESTClient() *restclient.RESTClient
SubjectAccessReviewsGetter
}
// AuthorizationClient is used to interact with features provided by the Authorization group.
type AuthorizationClient struct {
*restclient.RESTClient
}
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
return newSubjectAccessReviews(c)
}
// NewForConfig creates a new AuthorizationClient for the given config.
func NewForConfig(c *restclient.Config) (*AuthorizationClient, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthorizationClient{client}, nil
}
// NewForConfigOrDie creates a new AuthorizationClient for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *AuthorizationClient {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AuthorizationClient for the given RESTClient.
func New(c *restclient.RESTClient) *AuthorizationClient {
return &AuthorizationClient{c}
}
func setConfigDefaults(config *restclient.Config) error {
// if authorization group is not registered, return an error
g, err := registered.Group("authorization.k8s.io")
if err != nil {
return err
}
config.APIPath = "/apis"
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
if config.QPS == 0 {
config.QPS = 5
}
if config.Burst == 0 {
config.Burst = 10
}
return nil
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *AuthorizationClient) GetRESTClient() *restclient.RESTClient {
if c == nil {
return nil
}
return c.RESTClient
}
/*
Copyright 2016 The Kubernetes Authors.
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.
*/
// This package is generated by client-gen with the default arguments.
// This package has the automatically generated typed clients.
package unversioned
/*
Copyright 2016 The Kubernetes Authors.
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.
*/
// This package is generated by client-gen with the default arguments.
// Package fake has the automatically generated clients.
package fake
/*
Copyright 2016 The Kubernetes Authors.
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 fake
import (
unversioned "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
restclient "k8s.io/kubernetes/pkg/client/restclient"
core "k8s.io/kubernetes/pkg/client/testing/core"
)
type FakeAuthorization struct {
*core.Fake
}
func (c *FakeAuthorization) SubjectAccessReviews() unversioned.SubjectAccessReviewInterface {
return &FakeSubjectAccessReviews{c}
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeAuthorization) GetRESTClient() *restclient.RESTClient {
return nil
}
/*
Copyright 2016 The Kubernetes Authors.
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 fake
import (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/client/testing/core"
)
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
return obj.(*authorizationapi.SubjectAccessReview), err
}
/*
Copyright 2016 The Kubernetes Authors.
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 fake
// FakeSubjectAccessReviews implements SubjectAccessReviewInterface
type FakeSubjectAccessReviews struct {
Fake *FakeAuthorization
}
/*
Copyright 2016 The Kubernetes Authors.
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 (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
)
// The PodExpansion interface allows manually adding extra methods to the PodInterface.
type SubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
}
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
result = &authorizationapi.SubjectAccessReview{}
err = c.client.Post().
Resource("subjectaccessreviews").
Body(sar).
Do().
Into(result)
return
}
/*
Copyright 2016 The Kubernetes Authors.
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
// SubjectAccessReviewsGetter has a method to return a SubjectAccessReviewInterface.
// A group's client should implement this interface.
type SubjectAccessReviewsGetter interface {
SubjectAccessReviews() SubjectAccessReviewInterface
}
// SubjectAccessReviewInterface has methods to work with SubjectAccessReview resources.
type SubjectAccessReviewInterface interface {
SubjectAccessReviewExpansion
}
// subjectAccessReviews implements SubjectAccessReviewInterface
type subjectAccessReviews struct {
client *AuthorizationClient
}
// newSubjectAccessReviews returns a SubjectAccessReviews
func newSubjectAccessReviews(c *AuthorizationClient) *subjectAccessReviews {
return &subjectAccessReviews{
client: c,
}
}
...@@ -18,6 +18,7 @@ package release_1_4 ...@@ -18,6 +18,7 @@ package release_1_4
import ( import (
"github.com/golang/glog" "github.com/golang/glog"
v1beta1authorization "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/authorization/v1beta1"
v1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1" v1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1"
v1batch "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/batch/v1" v1batch "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/batch/v1"
v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/core/v1" v1core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/core/v1"
...@@ -30,9 +31,10 @@ import ( ...@@ -30,9 +31,10 @@ import (
type Interface interface { type Interface interface {
Discovery() discovery.DiscoveryInterface Discovery() discovery.DiscoveryInterface
Core() v1core.CoreInterface Core() v1core.CoreInterface
Extensions() v1beta1extensions.ExtensionsInterface Authorization() v1beta1authorization.AuthorizationInterface
Autoscaling() v1autoscaling.AutoscalingInterface Autoscaling() v1autoscaling.AutoscalingInterface
Batch() v1batch.BatchInterface Batch() v1batch.BatchInterface
Extensions() v1beta1extensions.ExtensionsInterface
} }
// Clientset contains the clients for groups. Each group has exactly one // Clientset contains the clients for groups. Each group has exactly one
...@@ -40,9 +42,10 @@ type Interface interface { ...@@ -40,9 +42,10 @@ type Interface interface {
type Clientset struct { type Clientset struct {
*discovery.DiscoveryClient *discovery.DiscoveryClient
*v1core.CoreClient *v1core.CoreClient
*v1beta1extensions.ExtensionsClient *v1beta1authorization.AuthorizationClient
*v1autoscaling.AutoscalingClient *v1autoscaling.AutoscalingClient
*v1batch.BatchClient *v1batch.BatchClient
*v1beta1extensions.ExtensionsClient
} }
// Core retrieves the CoreClient // Core retrieves the CoreClient
...@@ -53,12 +56,12 @@ func (c *Clientset) Core() v1core.CoreInterface { ...@@ -53,12 +56,12 @@ func (c *Clientset) Core() v1core.CoreInterface {
return c.CoreClient return c.CoreClient
} }
// Extensions retrieves the ExtensionsClient // Authorization retrieves the AuthorizationClient
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface { func (c *Clientset) Authorization() v1beta1authorization.AuthorizationInterface {
if c == nil { if c == nil {
return nil return nil
} }
return c.ExtensionsClient return c.AuthorizationClient
} }
// Autoscaling retrieves the AutoscalingClient // Autoscaling retrieves the AutoscalingClient
...@@ -77,6 +80,14 @@ func (c *Clientset) Batch() v1batch.BatchInterface { ...@@ -77,6 +80,14 @@ func (c *Clientset) Batch() v1batch.BatchInterface {
return c.BatchClient return c.BatchClient
} }
// Extensions retrieves the ExtensionsClient
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface {
if c == nil {
return nil
}
return c.ExtensionsClient
}
// Discovery retrieves the DiscoveryClient // Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface { func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.DiscoveryClient return c.DiscoveryClient
...@@ -94,7 +105,7 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -94,7 +105,7 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.ExtensionsClient, err = v1beta1extensions.NewForConfig(&configShallowCopy) clientset.AuthorizationClient, err = v1beta1authorization.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -106,6 +117,10 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -106,6 +117,10 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset.ExtensionsClient, err = v1beta1extensions.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
clientset.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) clientset.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
if err != nil { if err != nil {
...@@ -120,9 +135,10 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { ...@@ -120,9 +135,10 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
func NewForConfigOrDie(c *restclient.Config) *Clientset { func NewForConfigOrDie(c *restclient.Config) *Clientset {
var clientset Clientset var clientset Clientset
clientset.CoreClient = v1core.NewForConfigOrDie(c) clientset.CoreClient = v1core.NewForConfigOrDie(c)
clientset.ExtensionsClient = v1beta1extensions.NewForConfigOrDie(c) clientset.AuthorizationClient = v1beta1authorization.NewForConfigOrDie(c)
clientset.AutoscalingClient = v1autoscaling.NewForConfigOrDie(c) clientset.AutoscalingClient = v1autoscaling.NewForConfigOrDie(c)
clientset.BatchClient = v1batch.NewForConfigOrDie(c) clientset.BatchClient = v1batch.NewForConfigOrDie(c)
clientset.ExtensionsClient = v1beta1extensions.NewForConfigOrDie(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &clientset return &clientset
...@@ -132,9 +148,10 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset { ...@@ -132,9 +148,10 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset {
func New(c *restclient.RESTClient) *Clientset { func New(c *restclient.RESTClient) *Clientset {
var clientset Clientset var clientset Clientset
clientset.CoreClient = v1core.New(c) clientset.CoreClient = v1core.New(c)
clientset.ExtensionsClient = v1beta1extensions.New(c) clientset.AuthorizationClient = v1beta1authorization.New(c)
clientset.AutoscalingClient = v1autoscaling.New(c) clientset.AutoscalingClient = v1autoscaling.New(c)
clientset.BatchClient = v1batch.New(c) clientset.BatchClient = v1batch.New(c)
clientset.ExtensionsClient = v1beta1extensions.New(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c) clientset.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &clientset return &clientset
......
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated clientset. // This package has the automatically generated clientset.
package release_1_4 package release_1_4
...@@ -20,6 +20,8 @@ import ( ...@@ -20,6 +20,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4"
v1beta1authorization "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/authorization/v1beta1"
fakev1beta1authorization "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/authorization/v1beta1/fake"
v1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1" v1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1"
fakev1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1/fake" fakev1autoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/autoscaling/v1/fake"
v1batch "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/batch/v1" v1batch "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/batch/v1"
...@@ -73,9 +75,9 @@ func (c *Clientset) Core() v1core.CoreInterface { ...@@ -73,9 +75,9 @@ func (c *Clientset) Core() v1core.CoreInterface {
return &fakev1core.FakeCore{Fake: &c.Fake} return &fakev1core.FakeCore{Fake: &c.Fake}
} }
// Extensions retrieves the ExtensionsClient // Authorization retrieves the AuthorizationClient
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface { func (c *Clientset) Authorization() v1beta1authorization.AuthorizationInterface {
return &fakev1beta1extensions.FakeExtensions{Fake: &c.Fake} return &fakev1beta1authorization.FakeAuthorization{Fake: &c.Fake}
} }
// Autoscaling retrieves the AutoscalingClient // Autoscaling retrieves the AutoscalingClient
...@@ -87,3 +89,8 @@ func (c *Clientset) Autoscaling() v1autoscaling.AutoscalingInterface { ...@@ -87,3 +89,8 @@ func (c *Clientset) Autoscaling() v1autoscaling.AutoscalingInterface {
func (c *Clientset) Batch() v1batch.BatchInterface { func (c *Clientset) Batch() v1batch.BatchInterface {
return &fakev1batch.FakeBatch{Fake: &c.Fake} return &fakev1batch.FakeBatch{Fake: &c.Fake}
} }
// Extensions retrieves the ExtensionsClient
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface {
return &fakev1beta1extensions.FakeExtensions{Fake: &c.Fake}
}
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated fake clientset. // This package has the automatically generated fake clientset.
package fake package fake
/*
Copyright 2016 The Kubernetes Authors.
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 v1beta1
import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
serializer "k8s.io/kubernetes/pkg/runtime/serializer"
)
type AuthorizationInterface interface {
GetRESTClient() *restclient.RESTClient
SubjectAccessReviewsGetter
}
// AuthorizationClient is used to interact with features provided by the Authorization group.
type AuthorizationClient struct {
*restclient.RESTClient
}
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
return newSubjectAccessReviews(c)
}
// NewForConfig creates a new AuthorizationClient for the given config.
func NewForConfig(c *restclient.Config) (*AuthorizationClient, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthorizationClient{client}, nil
}
// NewForConfigOrDie creates a new AuthorizationClient for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *AuthorizationClient {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AuthorizationClient for the given RESTClient.
func New(c *restclient.RESTClient) *AuthorizationClient {
return &AuthorizationClient{c}
}
func setConfigDefaults(config *restclient.Config) error {
// if authorization group is not registered, return an error
g, err := registered.Group("authorization.k8s.io")
if err != nil {
return err
}
config.APIPath = "/apis"
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
return nil
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *AuthorizationClient) GetRESTClient() *restclient.RESTClient {
if c == nil {
return nil
}
return c.RESTClient
}
/*
Copyright 2016 The Kubernetes Authors.
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated typed clients.
package v1beta1
/*
Copyright 2016 The Kubernetes Authors.
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.
*/
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// Package fake has the automatically generated clients.
package fake
/*
Copyright 2016 The Kubernetes Authors.
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 fake
import (
v1beta1 "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_4/typed/authorization/v1beta1"
restclient "k8s.io/kubernetes/pkg/client/restclient"
core "k8s.io/kubernetes/pkg/client/testing/core"
)
type FakeAuthorization struct {
*core.Fake
}
func (c *FakeAuthorization) SubjectAccessReviews() v1beta1.SubjectAccessReviewInterface {
return &FakeSubjectAccessReviews{c}
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeAuthorization) GetRESTClient() *restclient.RESTClient {
return nil
}
/*
Copyright 2016 The Kubernetes Authors.
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 fake
import (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
"k8s.io/kubernetes/pkg/client/testing/core"
)
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
return obj.(*authorizationapi.SubjectAccessReview), err
}
/*
Copyright 2016 The Kubernetes Authors.
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 fake
// FakeSubjectAccessReviews implements SubjectAccessReviewInterface
type FakeSubjectAccessReviews struct {
Fake *FakeAuthorization
}
/*
Copyright 2016 The Kubernetes Authors.
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 v1beta1
import (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
)
// The PodExpansion interface allows manually adding extra methods to the PodInterface.
type SubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
}
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
result = &authorizationapi.SubjectAccessReview{}
err = c.client.Post().
Resource("subjectaccessreviews").
Body(sar).
Do().
Into(result)
return
}
/*
Copyright 2016 The Kubernetes Authors.
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 v1beta1
// SubjectAccessReviewsGetter has a method to return a SubjectAccessReviewInterface.
// A group's client should implement this interface.
type SubjectAccessReviewsGetter interface {
SubjectAccessReviews() SubjectAccessReviewInterface
}
// SubjectAccessReviewInterface has methods to work with SubjectAccessReview resources.
type SubjectAccessReviewInterface interface {
SubjectAccessReviewExpansion
}
// subjectAccessReviews implements SubjectAccessReviewInterface
type subjectAccessReviews struct {
client *AuthorizationClient
}
// newSubjectAccessReviews returns a SubjectAccessReviews
func newSubjectAccessReviews(c *AuthorizationClient) *subjectAccessReviews {
return &subjectAccessReviews{
client: c,
}
}
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated typed clients. // This package has the automatically generated typed clients.
package v1 package v1
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// Package fake has the automatically generated clients. // Package fake has the automatically generated clients.
package fake package fake
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated typed clients. // This package has the automatically generated typed clients.
package v1 package v1
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// Package fake has the automatically generated clients. // Package fake has the automatically generated clients.
package fake package fake
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated typed clients. // This package has the automatically generated typed clients.
package v1 package v1
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// Package fake has the automatically generated clients. // Package fake has the automatically generated clients.
package fake package fake
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// This package has the automatically generated typed clients. // This package has the automatically generated typed clients.
package v1beta1 package v1beta1
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,extensions/v1beta1,autoscaling/v1,batch/v1] // This package is generated by client-gen with arguments: --clientset-name=release_1_4 --input=[api/v1,authorization/v1beta1,autoscaling/v1,batch/v1,extensions/v1beta1]
// Package fake has the automatically generated clients. // Package fake has the automatically generated clients.
package fake package fake
...@@ -19,6 +19,7 @@ package internalclientset ...@@ -19,6 +19,7 @@ package internalclientset
import ( import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned" unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned"
unversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned" unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned"
unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned" unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned"
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned" unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
...@@ -47,6 +48,11 @@ func FromUnversionedClient(c *unversioned.Client) *internalclientset.Clientset { ...@@ -47,6 +48,11 @@ func FromUnversionedClient(c *unversioned.Client) *internalclientset.Clientset {
} else { } else {
clientset.BatchClient = unversionedbatch.New(nil) clientset.BatchClient = unversionedbatch.New(nil)
} }
if c != nil && c.AuthorizationClient != nil {
clientset.AuthorizationClient = unversionedauthorization.New(c.AuthorizationClient.RESTClient)
} else {
clientset.AuthorizationClient = unversionedauthorization.New(nil)
}
if c != nil && c.AutoscalingClient != nil { if c != nil && c.AutoscalingClient != nil {
clientset.AutoscalingClient = unversionedautoscaling.New(c.AutoscalingClient.RESTClient) clientset.AutoscalingClient = unversionedautoscaling.New(c.AutoscalingClient.RESTClient)
} else { } else {
......
/*
Copyright 2016 The Kubernetes Authors.
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/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/client/restclient"
)
type AuthorizationInterface interface {
SubjectAccessReviewsInterface
}
// AuthorizationClient is used to interact with Kubernetes authorization features.
type AuthorizationClient struct {
*restclient.RESTClient
}
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
return newSubjectAccessReviews(c)
}
func NewAuthorization(c *restclient.Config) (*AuthorizationClient, error) {
config := *c
if err := setAuthorizationDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthorizationClient{client}, nil
}
func NewAuthorizationOrDie(c *restclient.Config) *AuthorizationClient {
client, err := NewAuthorization(c)
if err != nil {
panic(err)
}
return client
}
func setAuthorizationDefaults(config *restclient.Config) error {
// if authorization group is not registered, return an error
g, err := registered.Group(authorization.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}
...@@ -45,6 +45,7 @@ type Interface interface { ...@@ -45,6 +45,7 @@ type Interface interface {
ComponentStatusesInterface ComponentStatusesInterface
ConfigMapsNamespacer ConfigMapsNamespacer
Apps() AppsInterface Apps() AppsInterface
Authorization() AuthorizationInterface
Autoscaling() AutoscalingInterface Autoscaling() AutoscalingInterface
Authentication() AuthenticationInterface Authentication() AuthenticationInterface
Batch() BatchInterface Batch() BatchInterface
...@@ -120,6 +121,7 @@ func (c *Client) ConfigMaps(namespace string) ConfigMapsInterface { ...@@ -120,6 +121,7 @@ func (c *Client) ConfigMaps(namespace string) ConfigMapsInterface {
// Client is the implementation of a Kubernetes client. // Client is the implementation of a Kubernetes client.
type Client struct { type Client struct {
*restclient.RESTClient *restclient.RESTClient
*AuthorizationClient
*AutoscalingClient *AutoscalingClient
*AuthenticationClient *AuthenticationClient
*BatchClient *BatchClient
...@@ -153,6 +155,10 @@ func IsTimeout(err error) bool { ...@@ -153,6 +155,10 @@ func IsTimeout(err error) bool {
return false return false
} }
func (c *Client) Authorization() AuthorizationInterface {
return c.AuthorizationClient
}
func (c *Client) Autoscaling() AutoscalingInterface { func (c *Client) Autoscaling() AutoscalingInterface {
return c.AutoscalingClient return c.AutoscalingClient
} }
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/authentication" "k8s.io/kubernetes/pkg/apis/authentication"
"k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/certificates"
...@@ -63,6 +64,15 @@ func New(c *restclient.Config) (*Client, error) { ...@@ -63,6 +64,15 @@ func New(c *restclient.Config) (*Client, error) {
return nil, err return nil, err
} }
var authorizationClient *AuthorizationClient
if registered.IsRegistered(authorization.GroupName) {
authorizationConfig := *c
authorizationClient, err = NewAuthorization(&authorizationConfig)
if err != nil {
return nil, err
}
}
var autoscalingClient *AutoscalingClient var autoscalingClient *AutoscalingClient
if registered.IsRegistered(autoscaling.GroupName) { if registered.IsRegistered(autoscaling.GroupName) {
autoscalingConfig := *c autoscalingConfig := *c
...@@ -137,6 +147,7 @@ func New(c *restclient.Config) (*Client, error) { ...@@ -137,6 +147,7 @@ func New(c *restclient.Config) (*Client, error) {
RESTClient: client, RESTClient: client,
AppsClient: appsClient, AppsClient: appsClient,
AuthenticationClient: authenticationClient, AuthenticationClient: authenticationClient,
AuthorizationClient: authorizationClient,
AutoscalingClient: autoscalingClient, AutoscalingClient: autoscalingClient,
BatchClient: batchClient, BatchClient: batchClient,
CertificatesClient: certsClient, CertificatesClient: certsClient,
......
/*
Copyright 2015 The Kubernetes Authors.
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/apis/authorization"
)
type SubjectAccessReviewsInterface interface {
SubjectAccessReviews() SubjectAccessReviewInterface
}
type SubjectAccessReviewInterface interface {
Create(subjectAccessReview *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error)
}
type subjectAccessReviews struct {
client *AuthorizationClient
}
func newSubjectAccessReviews(c *AuthorizationClient) *subjectAccessReviews {
return &subjectAccessReviews{
client: c,
}
}
func (c *subjectAccessReviews) Create(subjectAccessReview *authorization.SubjectAccessReview) (result *authorization.SubjectAccessReview, err error) {
result = &authorization.SubjectAccessReview{}
err = c.client.Post().Resource("subjectAccessReviews").Body(subjectAccessReview).Do().Into(result)
return
}
/*
Copyright 2015 The Kubernetes Authors.
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/apis/authorization"
)
// FakeSubjectAccessReviews implements SubjectAccessReviewInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the methods you want to test easier.
type FakeSubjectAccessReviews struct {
Fake *FakeAuthorization
}
func (c *FakeSubjectAccessReviews) Create(a *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error) {
obj, err := c.Fake.Invokes(NewRootCreateAction("subjectaccessreviews", a), a)
if obj == nil {
return nil, err
}
return obj.(*authorization.SubjectAccessReview), err
}
...@@ -281,6 +281,10 @@ func (c *Fake) Apps() client.AppsInterface { ...@@ -281,6 +281,10 @@ func (c *Fake) Apps() client.AppsInterface {
return &FakeApps{c} return &FakeApps{c}
} }
func (c *Fake) Authorization() client.AuthorizationInterface {
return &FakeAuthorization{c}
}
func (c *Fake) Autoscaling() client.AutoscalingInterface { func (c *Fake) Autoscaling() client.AutoscalingInterface {
return &FakeAutoscaling{c} return &FakeAutoscaling{c}
} }
...@@ -344,6 +348,19 @@ func (c *FakeApps) PetSets(namespace string) client.PetSetInterface { ...@@ -344,6 +348,19 @@ func (c *FakeApps) PetSets(namespace string) client.PetSetInterface {
return &FakePetSets{Fake: c, Namespace: namespace} return &FakePetSets{Fake: c, Namespace: namespace}
} }
// NewSimpleFakeAuthorization returns a client that will respond with the provided objects
func NewSimpleFakeAuthorization(objects ...runtime.Object) *FakeAuthorization {
return &FakeAuthorization{Fake: NewSimpleFake(objects...)}
}
type FakeAuthorization struct {
*Fake
}
func (c *FakeAuthorization) SubjectAccessReviews() client.SubjectAccessReviewInterface {
return &FakeSubjectAccessReviews{Fake: c}
}
// NewSimpleFakeAutoscaling returns a client that will respond with the provided objects // NewSimpleFakeAutoscaling returns a client that will respond with the provided objects
func NewSimpleFakeAutoscaling(objects ...runtime.Object) *FakeAutoscaling { func NewSimpleFakeAutoscaling(objects ...runtime.Object) *FakeAutoscaling {
return &FakeAutoscaling{Fake: NewSimpleFake(objects...)} return &FakeAutoscaling{Fake: NewSimpleFake(objects...)}
......
...@@ -503,11 +503,12 @@ func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversion ...@@ -503,11 +503,12 @@ func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversion
} }
var ignoredResources = map[unversioned.GroupVersionResource]struct{}{ var ignoredResources = map[unversioned.GroupVersionResource]struct{}{
unversioned.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicationcontrollers"}: {}, unversioned.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "replicationcontrollers"}: {},
unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "bindings"}: {}, unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "bindings"}: {},
unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "componentstatuses"}: {}, unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "componentstatuses"}: {},
unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "events"}: {}, unversioned.GroupVersionResource{Group: "", Version: "v1", Resource: "events"}: {},
unversioned.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1beta1", Resource: "tokenreviews"}: {}, unversioned.GroupVersionResource{Group: "authentication.k8s.io", Version: "v1beta1", Resource: "tokenreviews"}: {},
unversioned.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "subjectaccessreviews"}: {},
} }
func NewGarbageCollector(clientPool dynamic.ClientPool, resources []unversioned.GroupVersionResource) (*GarbageCollector, error) { func NewGarbageCollector(clientPool dynamic.ClientPool, resources []unversioned.GroupVersionResource) (*GarbageCollector, error) {
......
...@@ -35,6 +35,8 @@ import ( ...@@ -35,6 +35,8 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
appsapi "k8s.io/kubernetes/pkg/apis/apps/v1alpha1" appsapi "k8s.io/kubernetes/pkg/apis/apps/v1alpha1"
authenticationv1beta1 "k8s.io/kubernetes/pkg/apis/authentication/v1beta1" authenticationv1beta1 "k8s.io/kubernetes/pkg/apis/authentication/v1beta1"
"k8s.io/kubernetes/pkg/apis/authorization"
authorizationapiv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
"k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/autoscaling"
autoscalingapiv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1" autoscalingapiv1 "k8s.io/kubernetes/pkg/apis/autoscaling/v1"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
...@@ -202,6 +204,7 @@ func New(c *Config) (*Master, error) { ...@@ -202,6 +204,7 @@ func New(c *Config) (*Master, error) {
c.RESTStorageProviders[policy.GroupName] = PolicyRESTStorageProvider{} c.RESTStorageProviders[policy.GroupName] = PolicyRESTStorageProvider{}
c.RESTStorageProviders[rbac.GroupName] = RBACRESTStorageProvider{AuthorizerRBACSuperUser: c.AuthorizerRBACSuperUser} c.RESTStorageProviders[rbac.GroupName] = RBACRESTStorageProvider{AuthorizerRBACSuperUser: c.AuthorizerRBACSuperUser}
c.RESTStorageProviders[authenticationv1beta1.GroupName] = AuthenticationRESTStorageProvider{Authenticator: c.Authenticator} c.RESTStorageProviders[authenticationv1beta1.GroupName] = AuthenticationRESTStorageProvider{Authenticator: c.Authenticator}
c.RESTStorageProviders[authorization.GroupName] = AuthorizationRESTStorageProvider{Authorizer: c.Authorizer}
m.InstallAPIs(c) m.InstallAPIs(c)
// TODO: Attempt clean shutdown? // TODO: Attempt clean shutdown?
...@@ -762,6 +765,7 @@ func DefaultAPIResourceConfigSource() *genericapiserver.ResourceConfig { ...@@ -762,6 +765,7 @@ func DefaultAPIResourceConfigSource() *genericapiserver.ResourceConfig {
policyapiv1alpha1.SchemeGroupVersion, policyapiv1alpha1.SchemeGroupVersion,
rbacapi.SchemeGroupVersion, rbacapi.SchemeGroupVersion,
certificatesapiv1alpha1.SchemeGroupVersion, certificatesapiv1alpha1.SchemeGroupVersion,
authorizationapiv1beta1.SchemeGroupVersion,
) )
// all extensions resources except these are disabled by default // all extensions resources except these are disabled by default
......
/*
Copyright 2016 The Kubernetes Authors.
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 master
import (
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/authorization"
authorizationv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/registry/authorization/subjectaccessreview"
)
type AuthorizationRESTStorageProvider struct {
Authorizer authorizer.Authorizer
}
var _ RESTStorageProvider = &AuthorizationRESTStorageProvider{}
func (p AuthorizationRESTStorageProvider) NewRESTStorage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
if p.Authorizer == nil {
return genericapiserver.APIGroupInfo{}, false
}
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(authorization.GroupName)
if apiResourceConfigSource.AnyResourcesForVersionEnabled(authorizationv1beta1.SchemeGroupVersion) {
apiGroupInfo.VersionedResourcesStorageMap[authorizationv1beta1.SchemeGroupVersion.Version] = p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter)
apiGroupInfo.GroupMeta.GroupVersion = authorizationv1beta1.SchemeGroupVersion
}
return apiGroupInfo, true
}
func (p AuthorizationRESTStorageProvider) v1beta1Storage(apiResourceConfigSource genericapiserver.APIResourceConfigSource, restOptionsGetter RESTOptionsGetter) map[string]rest.Storage {
version := authorizationv1beta1.SchemeGroupVersion
storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("subjectaccessreviews")) {
storage["subjectaccessreviews"] = subjectaccessreview.NewREST(p.Authorizer)
}
return storage
}
/*
Copyright 2016 The Kubernetes Authors.
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 subjectaccessreview
import (
"fmt"
kapi "k8s.io/kubernetes/pkg/api"
kapierrors "k8s.io/kubernetes/pkg/api/errors"
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
authorizationvalidation "k8s.io/kubernetes/pkg/apis/authorization/validation"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/user"
authorizationutil "k8s.io/kubernetes/pkg/registry/authorization/util"
"k8s.io/kubernetes/pkg/runtime"
)
type REST struct {
authorizer authorizer.Authorizer
}
func NewREST(authorizer authorizer.Authorizer) *REST {
return &REST{authorizer}
}
func (r *REST) New() runtime.Object {
return &authorizationapi.SubjectAccessReview{}
}
func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview)
if !ok {
return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a SubjectAccessReview: %#v", obj))
}
if errs := authorizationvalidation.ValidateSubjectAccessReview(subjectAccessReview); len(errs) > 0 {
return nil, kapierrors.NewInvalid(authorizationapi.Kind(subjectAccessReview.Kind), "", errs)
}
userToCheck := &user.DefaultInfo{
Name: subjectAccessReview.Spec.User,
Groups: subjectAccessReview.Spec.Groups,
Extra: convertToUserInfoExtra(subjectAccessReview.Spec.Extra),
}
var authorizationAttributes authorizer.AttributesRecord
if subjectAccessReview.Spec.ResourceAttributes != nil {
authorizationAttributes = authorizationutil.ResourceAttributesFrom(userToCheck, *subjectAccessReview.Spec.ResourceAttributes)
} else {
authorizationAttributes = authorizationutil.NonResourceAttributesFrom(userToCheck, *subjectAccessReview.Spec.NonResourceAttributes)
}
allowed, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes)
subjectAccessReview.Status = authorizationapi.SubjectAccessReviewStatus{
Allowed: allowed,
Reason: reason,
}
if evaluationErr != nil {
subjectAccessReview.Status.EvaluationError = evaluationErr.Error()
}
return subjectAccessReview, nil
}
func convertToUserInfoExtra(extra map[string]authorizationapi.ExtraValue) map[string][]string {
if extra == nil {
return nil
}
ret := map[string][]string{}
for k, v := range extra {
ret[k] = []string(v)
}
return ret
}
/*
Copyright 2016 The Kubernetes Authors.
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 util
import (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/user"
)
// ResourceAttributesFrom combines the API object information and the user.Info from the context to build a full authorizer.AttributesRecord for resource access
func ResourceAttributesFrom(user user.Info, in authorizationapi.ResourceAttributes) authorizer.AttributesRecord {
return authorizer.AttributesRecord{
User: user,
Verb: in.Verb,
Namespace: in.Namespace,
APIGroup: in.Group,
Resource: in.Resource,
ResourceRequest: true,
}
}
// NonResourceAttributesFrom combines the API object information and the user.Info from the context to build a full authorizer.AttributesRecord for non resource access
func NonResourceAttributesFrom(user user.Info, in authorizationapi.NonResourceAttributes) authorizer.AttributesRecord {
return authorizer.AttributesRecord{
User: user,
ResourceRequest: false,
Path: in.Path,
}
}
...@@ -133,7 +133,7 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo ...@@ -133,7 +133,7 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo
r.Spec = v1beta1.SubjectAccessReviewSpec{ r.Spec = v1beta1.SubjectAccessReviewSpec{
User: user.GetName(), User: user.GetName(),
Groups: user.GetGroups(), Groups: user.GetGroups(),
Extra: user.GetExtra(), Extra: convertToSARExtra(user.GetExtra()),
} }
} }
...@@ -186,3 +186,15 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo ...@@ -186,3 +186,15 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo
} }
return r.Status.Allowed, r.Status.Reason, nil return r.Status.Allowed, r.Status.Reason, nil
} }
func convertToSARExtra(extra map[string][]string) map[string]v1beta1.ExtraValue {
if extra == nil {
return nil
}
ret := map[string]v1beta1.ExtraValue{}
for k, v := range extra {
ret[k] = v1beta1.ExtraValue(v)
}
return ret
}
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"user": "bob",
"groups": [
"the-group"
],
"resourceAttributes": {
"namespace": "ns",
"verb": "create",
"group": "autoscaling",
"resource": "horizontalpodautoscalers"
}
}
}
\ No newline at end of file
// +build integration,!no-etcd
/*
Copyright 2016 The Kubernetes Authors.
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 auth
import (
"errors"
"net/http"
"net/http/httptest"
"strings"
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/user"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/plugin/pkg/admission/admit"
"k8s.io/kubernetes/test/integration/framework"
)
// Inject into master an authorizer that uses user info.
// TODO(etune): remove this test once a more comprehensive built-in authorizer is implemented.
type sarAuthorizer struct{}
func (sarAuthorizer) Authorize(a authorizer.Attributes) (bool, string, error) {
if a.GetUser().GetName() == "dave" {
return false, "no", errors.New("I'm sorry, Dave")
}
return true, "you're not dave", nil
}
func alwaysAlice(req *http.Request) (user.Info, bool, error) {
return &user.DefaultInfo{
Name: "alice",
}, true, nil
}
func TestSubjectAccessReview(t *testing.T) {
// Set up a master
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
defer s.Close()
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.Authenticator = authenticator.RequestFunc(alwaysAlice)
masterConfig.Authorizer = sarAuthorizer{}
masterConfig.AdmissionControl = admit.NewAlwaysAdmit()
m, err := master.New(masterConfig)
if err != nil {
t.Fatalf("error in bringing up the master: %v", err)
}
clientset := clientset.NewForConfigOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}})
tests := []struct {
name string
sar *authorizationapi.SubjectAccessReview
expectedError string
expectedStatus authorizationapi.SubjectAccessReviewStatus
}{
{
name: "simple allow",
sar: &authorizationapi.SubjectAccessReview{
Spec: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{
Verb: "list",
Group: api.GroupName,
Version: "v1",
Resource: "pods",
},
User: "alice",
},
},
expectedStatus: authorizationapi.SubjectAccessReviewStatus{
Allowed: true,
Reason: "you're not dave",
},
},
{
name: "simple deny",
sar: &authorizationapi.SubjectAccessReview{
Spec: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{
Verb: "list",
Group: api.GroupName,
Version: "v1",
Resource: "pods",
},
User: "dave",
},
},
expectedStatus: authorizationapi.SubjectAccessReviewStatus{
Allowed: false,
Reason: "no",
EvaluationError: "I'm sorry, Dave",
},
},
{
name: "simple error",
sar: &authorizationapi.SubjectAccessReview{
Spec: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{
Verb: "list",
Group: api.GroupName,
Version: "v1",
Resource: "pods",
},
},
},
expectedError: "at least one of user or group must be specified",
},
}
for _, test := range tests {
response, err := clientset.Authorization().SubjectAccessReviews().Create(test.sar)
switch {
case err == nil && len(test.expectedError) == 0:
case err != nil && strings.Contains(err.Error(), test.expectedError):
continue
case err != nil && len(test.expectedError) != 0:
t.Errorf("%s: unexpected error: %v", test.name, err)
continue
default:
t.Errorf("%s: expected %v, got %v", test.name, test.expectedError, err)
continue
}
if response.Status != test.expectedStatus {
t.Errorf("%s: expected %v, got %v", test.name, test.expectedStatus, response.Status)
continue
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment