mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	add subjectaccessreviews resource
This commit is contained in:
		@@ -33,7 +33,16 @@ 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 {
 | 
				
			|||||||
			`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__
 | 
				
			|||||||
  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"
 | 
				
			|||||||
# 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:-}
 | 
				
			|||||||
# "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")
 | 
				
			|||||||
# 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=$!
 | 
				
			|||||||
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 (
 | 
				
			|||||||
	_ "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.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// +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.
 | 
				
			|||||||
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 {
 | 
				
			|||||||
// 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 {
 | 
				
			|||||||
// 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 {
 | 
				
			|||||||
	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 {
 | 
				
			|||||||
	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.
 | 
				
			|||||||
// +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"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			|||||||
// 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.
 | 
				
			|||||||
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 {
 | 
				
			|||||||
// 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 {
 | 
				
			|||||||
// 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 {
 | 
				
			|||||||
	// "" (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"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			|||||||
	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
 | 
				
			|||||||
	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
 | 
				
			|||||||
	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
 | 
				
			|||||||
	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
 | 
				
			|||||||
	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
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	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
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	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
 | 
				
			|||||||
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
 | 
				
			|||||||
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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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{},
 | 
				
			|||||||
		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
 | 
				
			|||||||
		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
 | 
				
			|||||||
		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
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		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{},
 | 
				
			|||||||
		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.
 | 
				
			|||||||
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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			|||||||
		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
 | 
				
			|||||||
		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{},
 | 
				
			|||||||
		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
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		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
 | 
				
			|||||||
		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
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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 {
 | 
				
			|||||||
	} 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 {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								pkg/client/unversioned/authorization.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								pkg/client/unversioned/authorization.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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 = ©GroupVersion
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config.NegotiatedSerializer = api.Codecs
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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 {
 | 
				
			|||||||
// 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 {
 | 
				
			|||||||
	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 (
 | 
				
			|||||||
	"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) {
 | 
				
			|||||||
		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) {
 | 
				
			|||||||
		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,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								pkg/client/unversioned/subjectaccessreview.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								pkg/client/unversioned/subjectaccessreview.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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 {
 | 
				
			|||||||
	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 {
 | 
				
			|||||||
	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...)}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -508,6 +508,7 @@ var ignoredResources = map[unversioned.GroupVersionResource]struct{}{
 | 
				
			|||||||
	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 (
 | 
				
			|||||||
	"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) {
 | 
				
			|||||||
	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 {
 | 
				
			|||||||
		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
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								pkg/master/storage_authorization.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								pkg/master/storage_authorization.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										89
									
								
								pkg/registry/authorization/subjectaccessreview/rest.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								pkg/registry/authorization/subjectaccessreview/rest.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								pkg/registry/authorization/util/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								pkg/registry/authorization/util/helpers.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			|||||||
		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
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								test/fixtures/pkg/kubectl/cmd/create/sar.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/fixtures/pkg/kubectl/cmd/create/sar.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "apiVersion": "authorization.k8s.io/v1beta1",
 | 
				
			||||||
 | 
					  "kind": "SubjectAccessReview",
 | 
				
			||||||
 | 
					  "spec": {
 | 
				
			||||||
 | 
					    "user": "bob",
 | 
				
			||||||
 | 
					    "groups": [
 | 
				
			||||||
 | 
					      "the-group"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "resourceAttributes": {
 | 
				
			||||||
 | 
					      "namespace": "ns",
 | 
				
			||||||
 | 
					      "verb": "create",
 | 
				
			||||||
 | 
					      "group": "autoscaling",
 | 
				
			||||||
 | 
					      "resource": "horizontalpodautoscalers"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										159
									
								
								test/integration/auth/accessreview_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								test/integration/auth/accessreview_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
				
			|||||||
 | 
					// +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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user