Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
022bff7f
Commit
022bff7f
authored
Feb 15, 2017
by
Andy Goldstein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch admission to use shared informers
parent
b437787a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
373 additions
and
433 deletions
+373
-433
BUILD
cmd/kube-apiserver/app/BUILD
+0
-1
server.go
cmd/kube-apiserver/app/server.go
+3
-8
BUILD
federation/cmd/federation-apiserver/app/BUILD
+1
-1
server.go
federation/cmd/federation-apiserver/app/server.go
+2
-2
BUILD
pkg/kubeapiserver/admission/BUILD
+1
-1
initializer.go
pkg/kubeapiserver/admission/initializer.go
+1
-1
BUILD
pkg/kubeapiserver/authorizer/BUILD
+4
-1
config.go
pkg/kubeapiserver/authorizer/config.go
+40
-5
BUILD
pkg/kubeapiserver/options/BUILD
+1
-1
authorization.go
pkg/kubeapiserver/options/authorization.go
+1
-1
BUILD
plugin/pkg/admission/limitranger/BUILD
+2
-2
admission.go
plugin/pkg/admission/limitranger/admission.go
+7
-6
admission_test.go
plugin/pkg/admission/limitranger/admission_test.go
+2
-2
BUILD
plugin/pkg/admission/namespace/autoprovision/BUILD
+3
-3
admission.go
plugin/pkg/admission/namespace/autoprovision/admission.go
+23
-17
admission_test.go
...n/pkg/admission/namespace/autoprovision/admission_test.go
+2
-2
BUILD
plugin/pkg/admission/namespace/exists/BUILD
+3
-3
admission.go
plugin/pkg/admission/namespace/exists/admission.go
+14
-20
admission_test.go
plugin/pkg/admission/namespace/exists/admission_test.go
+2
-2
BUILD
plugin/pkg/admission/namespace/lifecycle/BUILD
+3
-3
admission.go
plugin/pkg/admission/namespace/lifecycle/admission.go
+29
-22
admission_test.go
plugin/pkg/admission/namespace/lifecycle/admission_test.go
+2
-2
BUILD
plugin/pkg/admission/podnodeselector/BUILD
+3
-4
admission.go
plugin/pkg/admission/podnodeselector/admission.go
+15
-20
admission_test.go
plugin/pkg/admission/podnodeselector/admission_test.go
+6
-5
BUILD
plugin/pkg/admission/resourcequota/BUILD
+5
-2
admission.go
plugin/pkg/admission/resourcequota/admission.go
+22
-8
admission_test.go
plugin/pkg/admission/resourcequota/admission_test.go
+0
-0
resource_access.go
plugin/pkg/admission/resourcequota/resource_access.go
+9
-34
BUILD
plugin/pkg/admission/security/podsecuritypolicy/BUILD
+6
-7
admission.go
plugin/pkg/admission/security/podsecuritypolicy/admission.go
+20
-55
admission_test.go
...kg/admission/security/podsecuritypolicy/admission_test.go
+12
-10
BUILD
plugin/pkg/admission/serviceaccount/BUILD
+5
-4
admission.go
plugin/pkg/admission/serviceaccount/admission.go
+31
-80
admission_test.go
plugin/pkg/admission/serviceaccount/admission_test.go
+46
-29
BUILD
plugin/pkg/admission/storageclass/default/BUILD
+5
-5
admission.go
plugin/pkg/admission/storageclass/default/admission.go
+19
-58
admission_test.go
plugin/pkg/admission/storageclass/default/admission_test.go
+5
-2
policy.go
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
+6
-1
cluster-roles.yaml
...thorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml
+1
-0
quota_test.go
test/integration/quota/quota_test.go
+7
-0
service_account_test.go
test/integration/serviceaccount/service_account_test.go
+4
-3
No files found.
cmd/kube-apiserver/app/BUILD
View file @
022bff7f
...
...
@@ -23,7 +23,6 @@ go_library(
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/cloudprovider:go_default_library",
"//pkg/cloudprovider/providers:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/controller/serviceaccount:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/kubeapiserver:go_default_library",
...
...
cmd/kube-apiserver/app/server.go
View file @
022bff7f
...
...
@@ -51,9 +51,8 @@ import (
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/controller/informers"
serviceaccountcontroller
"k8s.io/kubernetes/pkg/controller/serviceaccount"
generatedopenapi
"k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/kubeapiserver"
...
...
@@ -270,17 +269,14 @@ func Run(s *options.ServerRunOptions) error {
glog
.
Errorf
(
"Failed to create clientset with KUBE_API_VERSIONS=%q. KUBE_API_VERSIONS is only for testing. Things will break."
,
kubeAPIVersions
)
}
// TODO: Internal informers should switch to using 'pkg/client/informers/informers_generated',
// the second informer created here. Refactor clients which take the former to accept the latter.
sharedInformers
:=
informers
.
NewSharedInformerFactory
(
nil
,
client
,
10
*
time
.
Minute
)
internalSharedInformers
:=
internalversion
.
NewSharedInformerFactory
(
client
,
10
*
time
.
Minute
)
sharedInformers
:=
informers
.
NewSharedInformerFactory
(
client
,
10
*
time
.
Minute
)
if
client
==
nil
{
// TODO: Remove check once client can never be nil.
glog
.
Errorf
(
"Failed to setup bootstrap token authenticator because the loopback clientset was not setup properly."
)
}
else
{
authenticatorConfig
.
BootstrapTokenAuthenticator
=
bootstrap
.
NewTokenAuthenticator
(
internalS
haredInformers
.
Core
()
.
InternalVersion
()
.
Secrets
()
.
Lister
()
.
Secrets
(
v1
.
NamespaceSystem
),
s
haredInformers
.
Core
()
.
InternalVersion
()
.
Secrets
()
.
Lister
()
.
Secrets
(
v1
.
NamespaceSystem
),
)
}
...
...
@@ -367,7 +363,6 @@ func Run(s *options.ServerRunOptions) error {
}
sharedInformers
.
Start
(
wait
.
NeverStop
)
internalSharedInformers
.
Start
(
wait
.
NeverStop
)
m
.
GenericAPIServer
.
PrepareRun
()
.
Run
(
wait
.
NeverStop
)
return
nil
}
...
...
federation/cmd/federation-apiserver/app/BUILD
View file @
022bff7f
...
...
@@ -36,8 +36,8 @@ go_library(
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/install:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/cloudprovider/providers:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/kubeapiserver:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
...
...
federation/cmd/federation-apiserver/app/server.go
View file @
022bff7f
...
...
@@ -41,7 +41,7 @@ import (
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
"k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/kubeapiserver"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
...
...
@@ -159,7 +159,7 @@ func Run(s *options.ServerRunOptions) error {
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create clientset: %v"
,
err
)
}
sharedInformers
:=
informers
.
NewSharedInformerFactory
(
nil
,
client
,
10
*
time
.
Minute
)
sharedInformers
:=
informers
.
NewSharedInformerFactory
(
client
,
10
*
time
.
Minute
)
authorizationConfig
:=
s
.
Authorization
.
ToAuthorizationConfig
(
sharedInformers
)
apiAuthorizer
,
err
:=
authorizationConfig
.
New
()
...
...
pkg/kubeapiserver/admission/BUILD
View file @
022bff7f
...
...
@@ -25,7 +25,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
],
...
...
pkg/kubeapiserver/admission/initializer.go
View file @
022bff7f
...
...
@@ -20,7 +20,7 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
)
// TODO add a `WantsToRun` which takes a stopCh. Might make it generic.
...
...
pkg/kubeapiserver/authorizer/BUILD
View file @
022bff7f
...
...
@@ -24,10 +24,13 @@ go_library(
srcs = ["config.go"],
tags = ["automanaged"],
deps = [
"//pkg/apis/rbac:go_default_library",
"//pkg/auth/authorizer/abac:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/rbac/internalversion:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizerfactory",
"//vendor:k8s.io/apiserver/pkg/authorization/union",
...
...
pkg/kubeapiserver/authorizer/config.go
View file @
022bff7f
...
...
@@ -21,12 +21,15 @@ import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
"k8s.io/apiserver/pkg/authorization/union"
"k8s.io/apiserver/plugin/pkg/authorizer/webhook"
rbacapi
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/controller/informers"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
rbaclisters
"k8s.io/kubernetes/pkg/client/listers/rbac/internalversion"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
)
...
...
@@ -56,6 +59,38 @@ type AuthorizationConfig struct {
InformerFactory
informers
.
SharedInformerFactory
}
type
roleGetter
struct
{
lister
rbaclisters
.
RoleLister
}
func
(
g
*
roleGetter
)
GetRole
(
namespace
,
name
string
)
(
*
rbacapi
.
Role
,
error
)
{
return
g
.
lister
.
Roles
(
namespace
)
.
Get
(
name
)
}
type
roleBindingLister
struct
{
lister
rbaclisters
.
RoleBindingLister
}
func
(
l
*
roleBindingLister
)
ListRoleBindings
(
namespace
string
)
([]
*
rbacapi
.
RoleBinding
,
error
)
{
return
l
.
lister
.
RoleBindings
(
namespace
)
.
List
(
labels
.
Everything
())
}
type
clusterRoleGetter
struct
{
lister
rbaclisters
.
ClusterRoleLister
}
func
(
g
*
clusterRoleGetter
)
GetClusterRole
(
name
string
)
(
*
rbacapi
.
ClusterRole
,
error
)
{
return
g
.
lister
.
Get
(
name
)
}
type
clusterRoleBindingLister
struct
{
lister
rbaclisters
.
ClusterRoleBindingLister
}
func
(
l
*
clusterRoleBindingLister
)
ListClusterRoleBindings
()
([]
*
rbacapi
.
ClusterRoleBinding
,
error
)
{
return
l
.
lister
.
List
(
labels
.
Everything
())
}
// New returns the right sort of union of multiple authorizer.Authorizer objects
// based on the authorizationMode or an error.
func
(
config
AuthorizationConfig
)
New
()
(
authorizer
.
Authorizer
,
error
)
{
...
...
@@ -98,10 +133,10 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
authorizers
=
append
(
authorizers
,
webhookAuthorizer
)
case
modes
.
ModeRBAC
:
rbacAuthorizer
:=
rbac
.
New
(
config
.
InformerFactory
.
Roles
()
.
Lister
()
,
config
.
InformerFactory
.
RoleBindings
()
.
Lister
()
,
config
.
InformerFactory
.
ClusterRoles
()
.
Lister
()
,
config
.
InformerFactory
.
ClusterRoleBindings
()
.
Lister
()
,
&
roleGetter
{
config
.
InformerFactory
.
Rbac
()
.
InternalVersion
()
.
Roles
()
.
Lister
()}
,
&
roleBindingLister
{
config
.
InformerFactory
.
Rbac
()
.
InternalVersion
()
.
RoleBindings
()
.
Lister
()}
,
&
clusterRoleGetter
{
config
.
InformerFactory
.
Rbac
()
.
InternalVersion
()
.
ClusterRoles
()
.
Lister
()}
,
&
clusterRoleBindingLister
{
config
.
InformerFactory
.
Rbac
()
.
InternalVersion
()
.
ClusterRoleBindings
()
.
Lister
()}
,
)
authorizers
=
append
(
authorizers
,
rbacAuthorizer
)
default
:
...
...
pkg/kubeapiserver/options/BUILD
View file @
022bff7f
...
...
@@ -21,8 +21,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/cloudprovider:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
...
...
pkg/kubeapiserver/options/authorization.go
View file @
022bff7f
...
...
@@ -22,7 +22,7 @@ import (
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
authzmodes
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
)
...
...
plugin/pkg/admission/limitranger/BUILD
View file @
022bff7f
...
...
@@ -18,8 +18,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:github.com/hashicorp/golang-lru",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
...
...
@@ -41,7 +41,7 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
...
...
plugin/pkg/admission/limitranger/admission.go
View file @
022bff7f
...
...
@@ -34,8 +34,8 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
coreinternallisters
"k8s.io/kubernetes/pkg/client/listers/core
/internalversion"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated
/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion
"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -54,7 +54,7 @@ type limitRanger struct {
*
admission
.
Handler
client
internalclientset
.
Interface
actions
LimitRangerActions
lister
core
internal
listers
.
LimitRangeLister
lister
corelisters
.
LimitRangeLister
// liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures.
// This let's us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results.
...
...
@@ -69,9 +69,9 @@ type liveLookupEntry struct {
}
func
(
l
*
limitRanger
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
limitRangeInformer
:=
f
.
InternalLimitRanges
()
.
Informer
()
l
.
SetReadyFunc
(
limitRangeInformer
.
HasSynced
)
l
.
lister
=
f
.
InternalLimitRanges
()
.
Lister
()
limitRangeInformer
:=
f
.
Core
()
.
InternalVersion
()
.
LimitRanges
()
l
.
SetReadyFunc
(
limitRangeInformer
.
Informer
()
.
HasSynced
)
l
.
lister
=
limitRangeInformer
.
Lister
()
}
func
(
l
*
limitRanger
)
Validate
()
error
{
...
...
@@ -167,6 +167,7 @@ func NewLimitRanger(actions LimitRangerActions) (admission.Interface, error) {
},
nil
}
var
_
=
kubeapiserveradmission
.
WantsInformerFactory
(
&
limitRanger
{})
var
_
=
kubeapiserveradmission
.
WantsInternalClientSet
(
&
limitRanger
{})
func
(
a
*
limitRanger
)
SetInternalClientSet
(
client
internalclientset
.
Interface
)
{
...
...
plugin/pkg/admission/limitranger/admission_test.go
View file @
022bff7f
...
...
@@ -32,7 +32,7 @@ import (
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
kubeadmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -590,7 +590,7 @@ func newMockClientForTest(limitRanges []api.LimitRange) *fake.Clientset {
// newHandlerForTest returns a handler configured for testing.
func
newHandlerForTest
(
c
clientset
.
Interface
)
(
admission
.
Interface
,
informers
.
SharedInformerFactory
,
error
)
{
f
:=
informers
.
NewSharedInformerFactory
(
nil
,
c
,
5
*
time
.
Minute
)
f
:=
informers
.
NewSharedInformerFactory
(
c
,
5
*
time
.
Minute
)
handler
,
err
:=
NewLimitRanger
(
&
DefaultLimitRangerActions
{})
if
err
!=
nil
{
return
nil
,
f
,
err
...
...
plugin/pkg/admission/namespace/autoprovision/BUILD
View file @
022bff7f
...
...
@@ -15,12 +15,12 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -33,7 +33,7 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
...
...
plugin/pkg/admission/namespace/autoprovision/admission.go
View file @
022bff7f
...
...
@@ -23,10 +23,10 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -41,14 +41,14 @@ func init() {
// It is useful in deployments that do not want to restrict creation of a namespace prior to its usage.
type
provision
struct
{
*
admission
.
Handler
client
internalclientset
.
Interface
namespace
Informer
cache
.
SharedIndexInform
er
client
internalclientset
.
Interface
namespace
Lister
corelisters
.
NamespaceList
er
}
var
_
=
kubeapiserveradmission
.
WantsInformerFactory
(
&
provision
{})
var
_
=
kubeapiserveradmission
.
WantsIn
formerFactory
(
&
provision
{})
var
_
=
kubeapiserveradmission
.
WantsIn
ternalClientSet
(
&
provision
{})
func
(
p
*
provision
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
func
(
p
*
provision
)
Admit
(
a
admission
.
Attributes
)
error
{
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
// its a namespaced resource.
...
...
@@ -59,6 +59,16 @@ func (p *provision) Admit(a admission.Attributes) (err error) {
if
!
p
.
WaitForReady
()
{
return
admission
.
NewForbidden
(
a
,
fmt
.
Errorf
(
"not yet ready to handle request"
))
}
_
,
err
:=
p
.
namespaceLister
.
Get
(
a
.
GetNamespace
())
if
err
==
nil
{
return
nil
}
if
!
errors
.
IsNotFound
(
err
)
{
return
admission
.
NewForbidden
(
a
,
err
)
}
namespace
:=
&
api
.
Namespace
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
a
.
GetNamespace
(),
...
...
@@ -66,17 +76,12 @@ func (p *provision) Admit(a admission.Attributes) (err error) {
},
Status
:
api
.
NamespaceStatus
{},
}
_
,
exists
,
err
:=
p
.
namespaceInformer
.
GetStore
()
.
Get
(
namespace
)
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
}
if
exists
{
return
nil
}
_
,
err
=
p
.
client
.
Core
()
.
Namespaces
()
.
Create
(
namespace
)
if
err
!=
nil
&&
!
errors
.
IsAlreadyExists
(
err
)
{
return
admission
.
NewForbidden
(
a
,
err
)
}
return
nil
}
...
...
@@ -92,13 +97,14 @@ func (p *provision) SetInternalClientSet(client internalclientset.Interface) {
}
func
(
p
*
provision
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
p
.
namespaceInformer
=
f
.
InternalNamespaces
()
.
Informer
()
p
.
SetReadyFunc
(
p
.
namespaceInformer
.
HasSynced
)
namespaceInformer
:=
f
.
Core
()
.
InternalVersion
()
.
Namespaces
()
p
.
namespaceLister
=
namespaceInformer
.
Lister
()
p
.
SetReadyFunc
(
namespaceInformer
.
Informer
()
.
HasSynced
)
}
func
(
p
*
provision
)
Validate
()
error
{
if
p
.
namespace
Inform
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
Inform
er"
)
if
p
.
namespace
List
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
List
er"
)
}
if
p
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
...
...
plugin/pkg/admission/namespace/autoprovision/admission_test.go
View file @
022bff7f
...
...
@@ -30,13 +30,13 @@ import (
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
kubeadmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
// newHandlerForTest returns the admission controller configured for testing.
func
newHandlerForTest
(
c
clientset
.
Interface
)
(
admission
.
Interface
,
informers
.
SharedInformerFactory
,
error
)
{
f
:=
informers
.
NewSharedInformerFactory
(
nil
,
c
,
5
*
time
.
Minute
)
f
:=
informers
.
NewSharedInformerFactory
(
c
,
5
*
time
.
Minute
)
handler
:=
NewProvision
()
pluginInitializer
:=
kubeadmission
.
NewPluginInitializer
(
c
,
f
,
nil
)
pluginInitializer
.
Initialize
(
handler
)
...
...
plugin/pkg/admission/namespace/exists/BUILD
View file @
022bff7f
...
...
@@ -15,12 +15,12 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -33,7 +33,7 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
...
...
plugin/pkg/admission/namespace/exists/admission.go
View file @
022bff7f
...
...
@@ -23,10 +23,10 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -41,14 +41,14 @@ func init() {
// It is useful in deployments that want to enforce pre-declaration of a Namespace resource.
type
exists
struct
{
*
admission
.
Handler
client
internalclientset
.
Interface
namespace
Informer
cache
.
SharedIndexInform
er
client
internalclientset
.
Interface
namespace
Lister
corelisters
.
NamespaceList
er
}
var
_
=
kubeapiserveradmission
.
WantsInformerFactory
(
&
exists
{})
var
_
=
kubeapiserveradmission
.
WantsInternalClientSet
(
&
exists
{})
func
(
e
*
exists
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
func
(
e
*
exists
)
Admit
(
a
admission
.
Attributes
)
error
{
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
// its a namespaced resource.
...
...
@@ -60,20 +60,13 @@ func (e *exists) Admit(a admission.Attributes) (err error) {
if
!
e
.
WaitForReady
()
{
return
admission
.
NewForbidden
(
a
,
fmt
.
Errorf
(
"not yet ready to handle request"
))
}
namespace
:=
&
api
.
Namespace
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
a
.
GetNamespace
(),
Namespace
:
""
,
},
Status
:
api
.
NamespaceStatus
{},
_
,
err
:=
e
.
namespaceLister
.
Get
(
a
.
GetNamespace
())
if
err
==
nil
{
return
nil
}
_
,
exists
,
err
:=
e
.
namespaceInformer
.
GetStore
()
.
Get
(
namespace
)
if
err
!=
nil
{
if
!
errors
.
IsNotFound
(
err
)
{
return
errors
.
NewInternalError
(
err
)
}
if
exists
{
return
nil
}
// in case of latency in our caches, make a call direct to storage to verify that it truly exists or not
_
,
err
=
e
.
client
.
Core
()
.
Namespaces
()
.
Get
(
a
.
GetNamespace
(),
metav1
.
GetOptions
{})
...
...
@@ -99,13 +92,14 @@ func (e *exists) SetInternalClientSet(client internalclientset.Interface) {
}
func
(
e
*
exists
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
e
.
namespaceInformer
=
f
.
InternalNamespaces
()
.
Informer
()
e
.
SetReadyFunc
(
e
.
namespaceInformer
.
HasSynced
)
namespaceInformer
:=
f
.
Core
()
.
InternalVersion
()
.
Namespaces
()
e
.
namespaceLister
=
namespaceInformer
.
Lister
()
e
.
SetReadyFunc
(
namespaceInformer
.
Informer
()
.
HasSynced
)
}
func
(
e
*
exists
)
Validate
()
error
{
if
e
.
namespace
Inform
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
Inform
er"
)
if
e
.
namespace
List
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
List
er"
)
}
if
e
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
...
...
plugin/pkg/admission/namespace/exists/admission_test.go
View file @
022bff7f
...
...
@@ -29,13 +29,13 @@ import (
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
kubeadmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
// newHandlerForTest returns the admission controller configured for testing.
func
newHandlerForTest
(
c
clientset
.
Interface
)
(
admission
.
Interface
,
informers
.
SharedInformerFactory
,
error
)
{
f
:=
informers
.
NewSharedInformerFactory
(
nil
,
c
,
5
*
time
.
Minute
)
f
:=
informers
.
NewSharedInformerFactory
(
c
,
5
*
time
.
Minute
)
handler
:=
NewExists
()
pluginInitializer
:=
kubeadmission
.
NewPluginInitializer
(
c
,
f
,
nil
)
pluginInitializer
.
Initialize
(
handler
)
...
...
plugin/pkg/admission/namespace/lifecycle/BUILD
View file @
022bff7f
...
...
@@ -15,7 +15,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
...
...
@@ -23,7 +24,6 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/util/cache",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/util/clock",
],
)
...
...
@@ -37,7 +37,7 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
...
...
plugin/pkg/admission/namespace/lifecycle/admission.go
View file @
022bff7f
...
...
@@ -28,11 +28,11 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission"
utilcache
"k8s.io/apiserver/pkg/util/cache"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/clock"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -61,7 +61,7 @@ type lifecycle struct {
*
admission
.
Handler
client
internalclientset
.
Interface
immortalNamespaces
sets
.
String
namespace
Informer
cache
.
SharedIndexInform
er
namespace
Lister
corelisters
.
NamespaceList
er
// forceLiveLookupCache holds a list of entries for namespaces that we have a strong reason to believe are stale in our local cache.
// if a namespace is in this cache, then we will ignore our local state and always fetch latest from api server.
forceLiveLookupCache
*
utilcache
.
LRUExpireCache
...
...
@@ -109,24 +109,31 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
}
var
(
namespaceObj
interface
{}
exists
bool
err
error
exists
bool
err
error
)
key
:=
makeNamespaceKey
(
a
.
GetNamespace
())
namespaceObj
,
exists
,
err
=
l
.
namespaceInformer
.
GetStore
()
.
Get
(
key
)
namespace
,
err
:=
l
.
namespaceLister
.
Get
(
a
.
GetNamespace
())
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
if
!
errors
.
IsNotFound
(
err
)
{
return
errors
.
NewInternalError
(
err
)
}
}
else
{
exists
=
true
}
if
!
exists
&&
a
.
GetOperation
()
==
admission
.
Create
{
// give the cache time to observe the namespace before rejecting a create.
// this helps when creating a namespace and immediately creating objects within it.
time
.
Sleep
(
missingNamespaceWait
)
namespaceObj
,
exists
,
err
=
l
.
namespaceInformer
.
GetStore
()
.
Get
(
key
)
if
err
!=
nil
{
namespace
,
err
=
l
.
namespaceLister
.
Get
(
a
.
GetNamespace
())
switch
{
case
errors
.
IsNotFound
(
err
)
:
// no-op
case
err
!=
nil
:
return
errors
.
NewInternalError
(
err
)
default
:
exists
=
true
}
if
exists
{
glog
.
V
(
4
)
.
Infof
(
"found %s in cache after waiting"
,
a
.
GetNamespace
())
...
...
@@ -137,17 +144,17 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
forceLiveLookup
:=
false
if
_
,
ok
:=
l
.
forceLiveLookupCache
.
Get
(
a
.
GetNamespace
());
ok
{
// we think the namespace was marked for deletion, but our current local cache says otherwise, we will force a live lookup.
forceLiveLookup
=
exists
&&
namespace
Obj
.
(
*
api
.
Namespace
)
.
Status
.
Phase
==
api
.
NamespaceActive
forceLiveLookup
=
exists
&&
namespace
.
Status
.
Phase
==
api
.
NamespaceActive
}
// refuse to operate on non-existent namespaces
if
!
exists
||
forceLiveLookup
{
// as a last resort, make a call directly to storage
namespace
Obj
,
err
=
l
.
client
.
Core
()
.
Namespaces
()
.
Get
(
a
.
GetNamespace
(),
metav1
.
GetOptions
{})
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
return
err
}
namespace
,
err
=
l
.
client
.
Core
()
.
Namespaces
()
.
Get
(
a
.
GetNamespace
(),
metav1
.
GetOptions
{})
switch
{
case
errors
.
IsNotFound
(
err
)
:
return
err
case
err
!=
nil
:
return
errors
.
NewInternalError
(
err
)
}
glog
.
V
(
4
)
.
Infof
(
"found %s via storage lookup"
,
a
.
GetNamespace
())
...
...
@@ -155,7 +162,6 @@ func (l *lifecycle) Admit(a admission.Attributes) error {
// ensure that we're not trying to create objects in terminating namespaces
if
a
.
GetOperation
()
==
admission
.
Create
{
namespace
:=
namespaceObj
.
(
*
api
.
Namespace
)
if
namespace
.
Status
.
Phase
!=
api
.
NamespaceTerminating
{
return
nil
}
...
...
@@ -182,8 +188,9 @@ func newLifecycleWithClock(immortalNamespaces sets.String, clock utilcache.Clock
}
func
(
l
*
lifecycle
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
l
.
namespaceInformer
=
f
.
InternalNamespaces
()
.
Informer
()
l
.
SetReadyFunc
(
l
.
namespaceInformer
.
HasSynced
)
namespaceInformer
:=
f
.
Core
()
.
InternalVersion
()
.
Namespaces
()
l
.
namespaceLister
=
namespaceInformer
.
Lister
()
l
.
SetReadyFunc
(
namespaceInformer
.
Informer
()
.
HasSynced
)
}
func
(
l
*
lifecycle
)
SetInternalClientSet
(
client
internalclientset
.
Interface
)
{
...
...
@@ -191,8 +198,8 @@ func (l *lifecycle) SetInternalClientSet(client internalclientset.Interface) {
}
func
(
l
*
lifecycle
)
Validate
()
error
{
if
l
.
namespace
Inform
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
Inform
er"
)
if
l
.
namespace
List
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
List
er"
)
}
if
l
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
...
...
plugin/pkg/admission/namespace/lifecycle/admission_test.go
View file @
022bff7f
...
...
@@ -31,7 +31,7 @@ import (
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
kubeadmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -42,7 +42,7 @@ func newHandlerForTest(c clientset.Interface) (admission.Interface, informers.Sh
// newHandlerForTestWithClock returns a configured handler for testing.
func
newHandlerForTestWithClock
(
c
clientset
.
Interface
,
cacheClock
clock
.
Clock
)
(
admission
.
Interface
,
informers
.
SharedInformerFactory
,
error
)
{
f
:=
informers
.
NewSharedInformerFactory
(
nil
,
c
,
5
*
time
.
Minute
)
f
:=
informers
.
NewSharedInformerFactory
(
c
,
5
*
time
.
Minute
)
handler
,
err
:=
newLifecycleWithClock
(
sets
.
NewString
(
metav1
.
NamespaceDefault
,
metav1
.
NamespaceSystem
),
cacheClock
)
if
err
!=
nil
{
return
nil
,
f
,
err
...
...
plugin/pkg/admission/podnodeselector/BUILD
View file @
022bff7f
...
...
@@ -15,7 +15,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
...
...
@@ -23,7 +24,6 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/util/yaml",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -36,11 +36,10 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/c
ontroller/informers
:go_default_library",
"//pkg/c
lient/informers/informers_generated/internalversion
:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apiserver/pkg/admission",
],
)
...
...
plugin/pkg/admission/podnodeselector/admission.go
View file @
022bff7f
...
...
@@ -28,10 +28,10 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -51,13 +51,14 @@ func init() {
// podNodeSelector is an implementation of admission.Interface.
type
podNodeSelector
struct
{
*
admission
.
Handler
client
internalclientset
.
Interface
namespace
Informer
cache
.
SharedIndexInform
er
client
internalclientset
.
Interface
namespace
Lister
corelisters
.
NamespaceList
er
// global default node selector and namespace whitelists in a cluster.
clusterNodeSelectors
map
[
string
]
string
}
var
_
=
kubeapiserveradmission
.
WantsInternalClientSet
(
&
podNodeSelector
{})
var
_
=
kubeapiserveradmission
.
WantsInformerFactory
(
&
podNodeSelector
{})
type
pluginConfig
struct
{
PodNodeSelectorPluginConfig
map
[
string
]
string
...
...
@@ -114,18 +115,8 @@ func (p *podNodeSelector) Admit(a admission.Attributes) error {
nsName
:=
a
.
GetNamespace
()
var
namespace
*
api
.
Namespace
namespaceObj
,
exists
,
err
:=
p
.
namespaceInformer
.
GetStore
()
.
Get
(
&
api
.
Namespace
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
nsName
,
Namespace
:
""
,
},
})
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
if
exists
{
namespace
=
namespaceObj
.
(
*
api
.
Namespace
)
}
else
{
namespace
,
err
:=
p
.
namespaceLister
.
Get
(
nsName
)
if
errors
.
IsNotFound
(
err
)
{
namespace
,
err
=
p
.
defaultGetNamespace
(
nsName
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
...
...
@@ -133,7 +124,10 @@ func (p *podNodeSelector) Admit(a admission.Attributes) error {
}
return
errors
.
NewInternalError
(
err
)
}
}
else
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
namespaceNodeSelector
,
err
:=
p
.
getNodeSelectorMap
(
namespace
)
if
err
!=
nil
{
return
err
...
...
@@ -173,13 +167,14 @@ func (a *podNodeSelector) SetInternalClientSet(client internalclientset.Interfac
}
func
(
p
*
podNodeSelector
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
p
.
namespaceInformer
=
f
.
InternalNamespaces
()
.
Informer
()
p
.
SetReadyFunc
(
p
.
namespaceInformer
.
HasSynced
)
namespaceInformer
:=
f
.
Core
()
.
InternalVersion
()
.
Namespaces
()
p
.
namespaceLister
=
namespaceInformer
.
Lister
()
p
.
SetReadyFunc
(
namespaceInformer
.
Informer
()
.
HasSynced
)
}
func
(
p
*
podNodeSelector
)
Validate
()
error
{
if
p
.
namespace
Inform
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
Inform
er"
)
if
p
.
namespace
List
er
==
nil
{
return
fmt
.
Errorf
(
"missing namespace
List
er"
)
}
if
p
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
...
...
plugin/pkg/admission/podnodeselector/admission_test.go
View file @
022bff7f
...
...
@@ -22,12 +22,11 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/informers
"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion
"
kubeadmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -45,7 +44,9 @@ func TestPodAdmission(t *testing.T) {
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error initializing handler: %v"
,
err
)
}
informerFactory
.
Start
(
wait
.
NeverStop
)
stopCh
:=
make
(
chan
struct
{})
defer
close
(
stopCh
)
informerFactory
.
Start
(
stopCh
)
pod
:=
&
api
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"testPod"
,
Namespace
:
"testNamespace"
},
...
...
@@ -144,7 +145,7 @@ func TestPodAdmission(t *testing.T) {
for
_
,
test
:=
range
tests
{
if
!
test
.
ignoreTestNamespaceNodeSelector
{
namespace
.
ObjectMeta
.
Annotations
=
map
[
string
]
string
{
"scheduler.alpha.kubernetes.io/node-selector"
:
test
.
namespaceNodeSelector
}
handler
.
namespaceInformer
.
GetStore
()
.
Update
(
namespace
)
informerFactory
.
Core
()
.
InternalVersion
()
.
Namespaces
()
.
Informer
()
.
GetStore
()
.
Update
(
namespace
)
}
handler
.
clusterNodeSelectors
=
make
(
map
[
string
]
string
)
handler
.
clusterNodeSelectors
[
"clusterDefaultNodeSelector"
]
=
test
.
defaultNodeSelector
...
...
@@ -180,7 +181,7 @@ func TestHandles(t *testing.T) {
// newHandlerForTest returns the admission controller configured for testing.
func
newHandlerForTest
(
c
clientset
.
Interface
)
(
*
podNodeSelector
,
informers
.
SharedInformerFactory
,
error
)
{
f
:=
informers
.
NewSharedInformerFactory
(
nil
,
c
,
5
*
time
.
Minute
)
f
:=
informers
.
NewSharedInformerFactory
(
c
,
5
*
time
.
Minute
)
handler
:=
NewPodNodeSelector
(
nil
)
pluginInitializer
:=
kubeadmission
.
NewPluginInitializer
(
c
,
f
,
nil
)
pluginInitializer
.
Initialize
(
handler
)
...
...
plugin/pkg/admission/resourcequota/BUILD
View file @
022bff7f
...
...
@@ -21,6 +21,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/quota:go_default_library",
"//pkg/quota/install:go_default_library",
...
...
@@ -35,16 +37,15 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
"//vendor:k8s.io/apimachinery/pkg/apimachinery/registered",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/storage/etcd",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/util/workqueue",
],
)
...
...
@@ -57,6 +58,8 @@ go_test(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/quota:go_default_library",
"//pkg/quota/generic:go_default_library",
"//pkg/quota/install:go_default_library",
...
...
plugin/pkg/admission/resourcequota/admission.go
View file @
022bff7f
...
...
@@ -24,6 +24,7 @@ import (
"k8s.io/apiserver/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
"k8s.io/kubernetes/pkg/quota"
"k8s.io/kubernetes/pkg/quota/install"
...
...
@@ -59,6 +60,7 @@ type quotaAdmission struct {
stopCh
<-
chan
struct
{}
registry
quota
.
Registry
numEvaluators
int
quotaAccessor
*
quotaAccessor
evaluator
Evaluator
}
...
...
@@ -73,29 +75,41 @@ type liveLookupEntry struct {
// using the provided registry. The registry must have the capability to handle group/kinds that
// are persisted by the server this admission controller is intercepting
func
NewResourceQuota
(
registry
quota
.
Registry
,
config
*
resourcequotaapi
.
Configuration
,
numEvaluators
int
,
stopCh
<-
chan
struct
{})
(
admission
.
Interface
,
error
)
{
quotaAccessor
,
err
:=
newQuotaAccessor
()
if
err
!=
nil
{
return
nil
,
err
}
return
&
quotaAdmission
{
Handler
:
admission
.
NewHandler
(
admission
.
Create
,
admission
.
Update
),
stopCh
:
stopCh
,
registry
:
registry
,
numEvaluators
:
numEvaluators
,
config
:
config
,
quotaAccessor
:
quotaAccessor
,
evaluator
:
NewQuotaEvaluator
(
quotaAccessor
,
registry
,
nil
,
config
,
numEvaluators
,
stopCh
),
},
nil
}
func
(
a
*
quotaAdmission
)
SetInternalClientSet
(
client
internalclientset
.
Interface
)
{
var
err
error
quotaAccessor
,
err
:=
newQuotaAccessor
(
client
)
if
err
!=
nil
{
// TODO handle errors more cleanly
panic
(
err
)
}
go
quotaAccessor
.
Run
(
a
.
stopCh
)
a
.
quotaAccessor
.
client
=
client
}
a
.
evaluator
=
NewQuotaEvaluator
(
quotaAccessor
,
a
.
registry
,
nil
,
a
.
config
,
a
.
numEvaluators
,
a
.
stopCh
)
func
(
a
*
quotaAdmission
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
a
.
quotaAccessor
.
lister
=
f
.
Core
()
.
InternalVersion
()
.
ResourceQuotas
()
.
Lister
()
}
// Validate ensures an authorizer is set.
func
(
a
*
quotaAdmission
)
Validate
()
error
{
if
a
.
quotaAccessor
==
nil
{
return
fmt
.
Errorf
(
"missing quotaAccessor"
)
}
if
a
.
quotaAccessor
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing quotaAccessor.client"
)
}
if
a
.
quotaAccessor
.
lister
==
nil
{
return
fmt
.
Errorf
(
"missing quotaAccessor.lister"
)
}
if
a
.
evaluator
==
nil
{
return
fmt
.
Errorf
(
"missing evaluator"
)
}
...
...
plugin/pkg/admission/resourcequota/admission_test.go
View file @
022bff7f
This diff is collapsed.
Click to expand it.
plugin/pkg/admission/resourcequota/resource_access.go
View file @
022bff7f
...
...
@@ -20,17 +20,14 @@ import (
"fmt"
"time"
"github.com/golang/glog"
lru
"github.com/hashicorp/golang-lru"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apiserver/pkg/storage/etcd"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
)
// QuotaAccessor abstracts the get/set logic from the rest of the Evaluator. This could be a test stub, a straight passthrough,
...
...
@@ -47,9 +44,8 @@ type QuotaAccessor interface {
type
quotaAccessor
struct
{
client
clientset
.
Interface
// indexer that holds quota objects by namespace
indexer
cache
.
Indexer
reflector
*
cache
.
Reflector
// lister can list/get quota objects from a shared informer's cache
lister
corelisters
.
ResourceQuotaLister
// liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures.
// This let's us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results.
...
...
@@ -63,7 +59,7 @@ type quotaAccessor struct {
}
// newQuotaAccessor creates an object that conforms to the QuotaAccessor interface to be used to retrieve quota objects.
func
newQuotaAccessor
(
client
clientset
.
Interface
)
(
*
quotaAccessor
,
error
)
{
func
newQuotaAccessor
()
(
*
quotaAccessor
,
error
)
{
liveLookupCache
,
err
:=
lru
.
New
(
100
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -72,36 +68,15 @@ func newQuotaAccessor(client clientset.Interface) (*quotaAccessor, error) {
if
err
!=
nil
{
return
nil
,
err
}
lw
:=
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
client
.
Core
()
.
ResourceQuotas
(
metav1
.
NamespaceAll
)
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
client
.
Core
()
.
ResourceQuotas
(
metav1
.
NamespaceAll
)
.
Watch
(
options
)
},
}
indexer
,
reflector
:=
cache
.
NewNamespaceKeyedIndexerAndReflector
(
lw
,
&
api
.
ResourceQuota
{},
0
)
// client and lister will be set when SetInternalClientSet and SetInformerFactory are invoked
return
&
quotaAccessor
{
client
:
client
,
indexer
:
indexer
,
reflector
:
reflector
,
liveLookupCache
:
liveLookupCache
,
liveTTL
:
time
.
Duration
(
30
*
time
.
Second
),
updatedQuotas
:
updatedCache
,
},
nil
}
// Run begins watching and syncing.
func
(
e
*
quotaAccessor
)
Run
(
stopCh
<-
chan
struct
{})
{
defer
utilruntime
.
HandleCrash
()
e
.
reflector
.
RunUntil
(
stopCh
)
<-
stopCh
glog
.
Infof
(
"Shutting down quota accessor"
)
}
func
(
e
*
quotaAccessor
)
UpdateQuotaStatus
(
newQuota
*
api
.
ResourceQuota
)
error
{
updatedQuota
,
err
:=
e
.
client
.
Core
()
.
ResourceQuotas
(
newQuota
.
Namespace
)
.
UpdateStatus
(
newQuota
)
if
err
!=
nil
{
...
...
@@ -136,9 +111,9 @@ func (e *quotaAccessor) checkCache(quota *api.ResourceQuota) *api.ResourceQuota
func
(
e
*
quotaAccessor
)
GetQuotas
(
namespace
string
)
([]
api
.
ResourceQuota
,
error
)
{
// determine if there are any quotas in this namespace
// if there are no quotas, we don't need to do anything
items
,
err
:=
e
.
indexer
.
Index
(
"namespace"
,
&
api
.
ResourceQuota
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
namespace
,
Name
:
""
}}
)
items
,
err
:=
e
.
lister
.
ResourceQuotas
(
namespace
)
.
List
(
labels
.
Everything
()
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error resolving quota
."
)
return
nil
,
fmt
.
Errorf
(
"error resolving quota
: %v"
,
err
)
}
// if there are no items held in our indexer, check our live-lookup LRU, if that misses, do the live lookup to prime it.
...
...
@@ -169,7 +144,7 @@ func (e *quotaAccessor) GetQuotas(namespace string) ([]api.ResourceQuota, error)
resourceQuotas
:=
[]
api
.
ResourceQuota
{}
for
i
:=
range
items
{
quota
:=
items
[
i
]
.
(
*
api
.
ResourceQuota
)
quota
:=
items
[
i
]
quota
=
e
.
checkCache
(
quota
)
// always make a copy. We're going to muck around with this and we should never mutate the originals
resourceQuotas
=
append
(
resourceQuotas
,
*
quota
)
...
...
plugin/pkg/admission/security/podsecuritypolicy/BUILD
View file @
022bff7f
...
...
@@ -15,7 +15,8 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/extensions/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/security/podsecuritypolicy:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library",
...
...
@@ -23,15 +24,11 @@ go_library(
"//pkg/serviceaccount:go_default_library",
"//pkg/util/maps:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -43,6 +40,9 @@ go_test(
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/extensions/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library",
...
...
@@ -54,7 +54,6 @@ go_test(
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/authentication/user",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
plugin/pkg/admission/security/podsecuritypolicy/admission.go
View file @
022bff7f
...
...
@@ -23,18 +23,15 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
extensionslisters
"k8s.io/kubernetes/pkg/client/listers/extensions/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
psp
"k8s.io/kubernetes/pkg/security/podsecuritypolicy"
psputil
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
...
...
@@ -55,7 +52,7 @@ func init() {
}
// PSPMatchFn allows plugging in how PSPs are matched against user information.
type
PSPMatchFn
func
(
store
cache
.
Store
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
type
PSPMatchFn
func
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
// podSecurityPolicyPlugin holds state for and implements the admission plugin.
type
podSecurityPolicyPlugin
struct
{
...
...
@@ -64,10 +61,7 @@ type podSecurityPolicyPlugin struct {
pspMatcher
PSPMatchFn
failOnNoPolicies
bool
authz
authorizer
.
Authorizer
reflector
*
cache
.
Reflector
stopChan
chan
struct
{}
store
cache
.
Store
lister
extensionslisters
.
PodSecurityPolicyLister
}
// SetAuthorizer sets the authorizer.
...
...
@@ -80,22 +74,18 @@ func (plugin *podSecurityPolicyPlugin) Validate() error {
if
plugin
.
authz
==
nil
{
return
fmt
.
Errorf
(
"%s requires an authorizer"
,
PluginName
)
}
if
plugin
.
store
==
nil
{
return
fmt
.
Errorf
(
"%s requires an client"
,
PluginName
)
}
if
plugin
.
store
==
nil
{
return
fmt
.
Errorf
(
"%s requires an client"
,
PluginName
)
if
plugin
.
lister
==
nil
{
return
fmt
.
Errorf
(
"%s requires a lister"
,
PluginName
)
}
return
nil
}
var
_
admission
.
Interface
=
&
podSecurityPolicyPlugin
{}
var
_
kubeapiserveradmission
.
WantsAuthorizer
=
&
podSecurityPolicyPlugin
{}
var
_
kubeapiserveradmission
.
WantsIn
ternalClientSet
=
&
podSecurityPolicyPlugin
{}
var
_
kubeapiserveradmission
.
WantsIn
formerFactory
=
&
podSecurityPolicyPlugin
{}
// NewPlugin creates a new PSP admission plugin.
func
NewPlugin
(
strategyFactory
psp
.
StrategyFactory
,
pspMatcher
PSPMatchFn
,
failOnNoPolicies
bool
)
*
podSecurityPolicyPlugin
{
return
&
podSecurityPolicyPlugin
{
Handler
:
admission
.
NewHandler
(
admission
.
Create
,
admission
.
Update
),
strategyFactory
:
strategyFactory
,
...
...
@@ -104,35 +94,10 @@ func NewPlugin(strategyFactory psp.StrategyFactory, pspMatcher PSPMatchFn, failO
}
}
func
(
a
*
podSecurityPolicyPlugin
)
SetInternalClientSet
(
client
internalclientset
.
Interface
)
{
a
.
store
=
cache
.
NewStore
(
cache
.
MetaNamespaceKeyFunc
)
a
.
reflector
=
cache
.
NewReflector
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
client
.
Extensions
()
.
PodSecurityPolicies
()
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
client
.
Extensions
()
.
PodSecurityPolicies
()
.
Watch
(
options
)
},
},
&
extensions
.
PodSecurityPolicy
{},
a
.
store
,
0
,
)
a
.
Run
()
}
func
(
a
*
podSecurityPolicyPlugin
)
Run
()
{
if
a
.
stopChan
==
nil
{
a
.
stopChan
=
make
(
chan
struct
{})
}
a
.
reflector
.
RunUntil
(
a
.
stopChan
)
}
func
(
a
*
podSecurityPolicyPlugin
)
Stop
()
{
if
a
.
stopChan
!=
nil
{
close
(
a
.
stopChan
)
a
.
stopChan
=
nil
}
func
(
a
*
podSecurityPolicyPlugin
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
podSecurityPolicyInformer
:=
f
.
Extensions
()
.
InternalVersion
()
.
PodSecurityPolicies
()
a
.
lister
=
podSecurityPolicyInformer
.
Lister
()
a
.
SetReadyFunc
(
podSecurityPolicyInformer
.
Informer
()
.
HasSynced
)
}
// Admit determines if the pod should be admitted based on the requested security context
...
...
@@ -165,7 +130,7 @@ func (c *podSecurityPolicyPlugin) Admit(a admission.Attributes) error {
saInfo
=
serviceaccount
.
UserInfo
(
a
.
GetNamespace
(),
pod
.
Spec
.
ServiceAccountName
,
""
)
}
matchedPolicies
,
err
:=
c
.
pspMatcher
(
c
.
store
,
a
.
GetUserInfo
(),
saInfo
,
c
.
authz
)
matchedPolicies
,
err
:=
c
.
pspMatcher
(
c
.
lister
,
a
.
GetUserInfo
(),
saInfo
,
c
.
authz
)
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
}
...
...
@@ -308,21 +273,21 @@ func (c *podSecurityPolicyPlugin) createProvidersFromPolicies(psps []*extensions
return
providers
,
errs
}
// getMatchingPolicies returns policies from the
store
. For now this returns everything
// getMatchingPolicies returns policies from the
lister
. For now this returns everything
// in the future it can filter based on UserInfo and permissions.
//
// TODO: this will likely need optimization since the initial implementation will
// always query for authorization. Needs scale testing and possibly checking against
// a cache.
func
getMatchingPolicies
(
store
cache
.
Store
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
{
func
getMatchingPolicies
(
lister
extensionslisters
.
PodSecurityPolicyLister
,
user
user
.
Info
,
sa
user
.
Info
,
authz
authorizer
.
Authorizer
)
([]
*
extensions
.
PodSecurityPolicy
,
error
)
{
matchedPolicies
:=
make
([]
*
extensions
.
PodSecurityPolicy
,
0
)
for
_
,
c
:=
range
store
.
List
()
{
constraint
,
ok
:=
c
.
(
*
extensions
.
PodSecurityPolicy
)
if
!
ok
{
return
nil
,
errors
.
NewInternalError
(
fmt
.
Errorf
(
"error converting object from store to a pod security policy: %v"
,
c
))
}
list
,
err
:=
lister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
constraint
:=
range
list
{
if
authorizedForPolicy
(
user
,
constraint
,
authz
)
||
authorizedForPolicy
(
sa
,
constraint
,
authz
)
{
matchedPolicies
=
append
(
matchedPolicies
,
constraint
)
}
...
...
plugin/pkg/admission/security/podsecuritypolicy/admission_test.go
View file @
022bff7f
...
...
@@ -30,9 +30,11 @@ import (
kadmission
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/tools/cache"
kapi
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
extensionslisters
"k8s.io/kubernetes/pkg/client/listers/extensions/internalversion"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/security/apparmor"
kpsp
"k8s.io/kubernetes/pkg/security/podsecuritypolicy"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
...
...
@@ -43,13 +45,13 @@ const defaultContainerName = "test-c"
// NewTestAdmission provides an admission plugin with test implementations of internal structs. It uses
// an authorizer that always returns true.
func
NewTestAdmission
(
store
cache
.
Store
)
kadmission
.
Interface
{
func
NewTestAdmission
(
lister
extensionslisters
.
PodSecurityPolicyLister
)
kadmission
.
Interface
{
return
&
podSecurityPolicyPlugin
{
Handler
:
kadmission
.
NewHandler
(
kadmission
.
Create
),
store
:
store
,
strategyFactory
:
kpsp
.
NewSimpleStrategyFactory
(),
pspMatcher
:
getMatchingPolicies
,
authz
:
&
TestAuthorizer
{},
lister
:
lister
,
}
}
...
...
@@ -1337,13 +1339,14 @@ func TestAdmitSysctls(t *testing.T) {
}
func
testPSPAdmit
(
testCaseName
string
,
psps
[]
*
extensions
.
PodSecurityPolicy
,
pod
*
kapi
.
Pod
,
shouldPass
bool
,
expectedPSP
string
,
t
*
testing
.
T
)
{
store
:=
cache
.
NewStore
(
cache
.
MetaNamespaceKeyFunc
)
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
store
:=
informerFactory
.
Extensions
()
.
InternalVersion
()
.
PodSecurityPolicies
()
.
Informer
()
.
GetStore
()
for
_
,
psp
:=
range
psps
{
store
.
Add
(
psp
)
}
plugin
:=
NewTestAdmission
(
store
)
plugin
:=
NewTestAdmission
(
informerFactory
.
Extensions
()
.
InternalVersion
()
.
PodSecurityPolicies
()
.
Lister
()
)
attrs
:=
kadmission
.
NewAttributesRecord
(
pod
,
nil
,
kapi
.
Kind
(
"Pod"
)
.
WithVersion
(
"version"
),
"namespace"
,
""
,
kapi
.
Resource
(
"pods"
)
.
WithVersion
(
"version"
),
""
,
kadmission
.
Create
,
&
user
.
DefaultInfo
{})
err
:=
plugin
.
Admit
(
attrs
)
...
...
@@ -1505,11 +1508,8 @@ func TestCreateProvidersFromConstraints(t *testing.T) {
}
for
k
,
v
:=
range
testCases
{
store
:=
cache
.
NewStore
(
cache
.
MetaNamespaceKeyFunc
)
admit
:=
&
podSecurityPolicyPlugin
{
Handler
:
kadmission
.
NewHandler
(
kadmission
.
Create
,
kadmission
.
Update
),
store
:
store
,
strategyFactory
:
kpsp
.
NewSimpleStrategyFactory
(),
}
...
...
@@ -1628,13 +1628,15 @@ func TestGetMatchingPolicies(t *testing.T) {
},
}
for
k
,
v
:=
range
tests
{
store
:=
cache
.
NewStore
(
cache
.
MetaNamespaceKeyFunc
)
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
pspInformer
:=
informerFactory
.
Extensions
()
.
InternalVersion
()
.
PodSecurityPolicies
()
store
:=
pspInformer
.
Informer
()
.
GetStore
()
for
_
,
psp
:=
range
v
.
inPolicies
{
store
.
Add
(
psp
)
}
authz
:=
&
TestAuthorizer
{
disallowed
:
v
.
disallowedPolicies
}
allowedPolicies
,
err
:=
getMatchingPolicies
(
store
,
v
.
user
,
v
.
sa
,
authz
)
allowedPolicies
,
err
:=
getMatchingPolicies
(
pspInformer
.
Lister
()
,
v
.
user
,
v
.
sa
,
authz
)
if
err
!=
nil
{
t
.
Errorf
(
"%s got unexpected error %#v"
,
k
,
err
)
continue
...
...
plugin/pkg/admission/serviceaccount/BUILD
View file @
022bff7f
...
...
@@ -18,19 +18,18 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubelet/types:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/fields",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/apiserver/pkg/storage/names",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -42,6 +41,8 @@ go_test(
deps = [
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/kubelet/types:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
...
...
plugin/pkg/admission/serviceaccount/admission.go
View file @
022bff7f
...
...
@@ -25,16 +25,15 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/storage/names"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubelet
"k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/serviceaccount"
...
...
@@ -75,15 +74,12 @@ type serviceAccount struct {
client
internalclientset
.
Interface
serviceAccounts
cache
.
Indexer
secrets
cache
.
Indexer
stopChan
chan
struct
{}
serviceAccountsReflector
*
cache
.
Reflector
secretsReflector
*
cache
.
Reflector
serviceAccountLister
corelisters
.
ServiceAccountLister
secretLister
corelisters
.
SecretLister
}
var
_
=
kubeapiserveradmission
.
WantsInternalClientSet
(
&
serviceAccount
{})
var
_
=
kubeapiserveradmission
.
WantsInformerFactory
(
&
serviceAccount
{})
// NewServiceAccount returns an admission.Interface implementation which limits admission of Pod CREATE requests based on the pod's ServiceAccount:
// 1. If the pod does not specify a ServiceAccount, it sets the pod's ServiceAccount to "default"
...
...
@@ -105,38 +101,18 @@ func NewServiceAccount() *serviceAccount {
func
(
a
*
serviceAccount
)
SetInternalClientSet
(
cl
internalclientset
.
Interface
)
{
a
.
client
=
cl
a
.
serviceAccounts
,
a
.
serviceAccountsReflector
=
cache
.
NewNamespaceKeyedIndexerAndReflector
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
cl
.
Core
()
.
ServiceAccounts
(
metav1
.
NamespaceAll
)
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
cl
.
Core
()
.
ServiceAccounts
(
metav1
.
NamespaceAll
)
.
Watch
(
options
)
},
},
&
api
.
ServiceAccount
{},
0
,
)
tokenSelector
:=
fields
.
SelectorFromSet
(
map
[
string
]
string
{
api
.
SecretTypeField
:
string
(
api
.
SecretTypeServiceAccountToken
)})
a
.
secrets
,
a
.
secretsReflector
=
cache
.
NewNamespaceKeyedIndexerAndReflector
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
options
.
FieldSelector
=
tokenSelector
.
String
()
return
cl
.
Core
()
.
Secrets
(
metav1
.
NamespaceAll
)
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
options
.
FieldSelector
=
tokenSelector
.
String
()
return
cl
.
Core
()
.
Secrets
(
metav1
.
NamespaceAll
)
.
Watch
(
options
)
},
},
&
api
.
Secret
{},
0
,
)
}
if
cl
!=
nil
{
a
.
Run
()
}
func
(
a
*
serviceAccount
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
serviceAccountInformer
:=
f
.
Core
()
.
InternalVersion
()
.
ServiceAccounts
()
a
.
serviceAccountLister
=
serviceAccountInformer
.
Lister
()
secretInformer
:=
f
.
Core
()
.
InternalVersion
()
.
Secrets
()
a
.
secretLister
=
secretInformer
.
Lister
()
a
.
SetReadyFunc
(
func
()
bool
{
return
serviceAccountInformer
.
Informer
()
.
HasSynced
()
&&
secretInformer
.
Informer
()
.
HasSynced
()
})
}
// Validate ensures an authorizer is set.
...
...
@@ -144,35 +120,15 @@ func (a *serviceAccount) Validate() error {
if
a
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
}
if
a
.
secret
s
==
nil
{
return
fmt
.
Errorf
(
"missing secret
sIndex
er"
)
if
a
.
secret
Lister
==
nil
{
return
fmt
.
Errorf
(
"missing secret
List
er"
)
}
if
a
.
secretsReflector
==
nil
{
return
fmt
.
Errorf
(
"missing secretsReflector"
)
}
if
a
.
serviceAccounts
==
nil
{
return
fmt
.
Errorf
(
"missing serviceAccountsIndexer"
)
}
if
a
.
serviceAccountsReflector
==
nil
{
return
fmt
.
Errorf
(
"missing serviceAccountsReflector"
)
if
a
.
serviceAccountLister
==
nil
{
return
fmt
.
Errorf
(
"missing serviceAccountLister"
)
}
return
nil
}
func
(
s
*
serviceAccount
)
Run
()
{
if
s
.
stopChan
==
nil
{
s
.
stopChan
=
make
(
chan
struct
{})
s
.
serviceAccountsReflector
.
RunUntil
(
s
.
stopChan
)
s
.
secretsReflector
.
RunUntil
(
s
.
stopChan
)
}
}
func
(
s
*
serviceAccount
)
Stop
()
{
if
s
.
stopChan
!=
nil
{
close
(
s
.
stopChan
)
s
.
stopChan
=
nil
}
}
func
(
s
*
serviceAccount
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
if
a
.
GetResource
()
.
GroupResource
()
!=
api
.
Resource
(
"pods"
)
{
return
nil
...
...
@@ -269,17 +225,12 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAcco
// getServiceAccount returns the ServiceAccount for the given namespace and name if it exists
func
(
s
*
serviceAccount
)
getServiceAccount
(
namespace
string
,
name
string
)
(
*
api
.
ServiceAccount
,
error
)
{
key
:=
&
api
.
ServiceAccount
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
namespace
}}
index
,
err
:=
s
.
serviceAccounts
.
Index
(
"namespace"
,
key
)
if
err
!=
nil
{
return
nil
,
err
serviceAccount
,
err
:=
s
.
serviceAccountLister
.
ServiceAccounts
(
namespace
)
.
Get
(
name
)
if
err
==
nil
{
return
serviceAccount
,
nil
}
for
_
,
obj
:=
range
index
{
serviceAccount
:=
obj
.
(
*
api
.
ServiceAccount
)
if
serviceAccount
.
Name
==
name
{
return
serviceAccount
,
nil
}
if
!
errors
.
IsNotFound
(
err
)
{
return
nil
,
err
}
// Could not find in cache, attempt to look up directly
...
...
@@ -332,15 +283,15 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *api.Se
// getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount
func
(
s
*
serviceAccount
)
getServiceAccountTokens
(
serviceAccount
*
api
.
ServiceAccount
)
([]
*
api
.
Secret
,
error
)
{
key
:=
&
api
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Namespace
:
serviceAccount
.
Namespace
}}
index
,
err
:=
s
.
secrets
.
Index
(
"namespace"
,
key
)
tokens
,
err
:=
s
.
secretLister
.
Secrets
(
serviceAccount
.
Namespace
)
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
tokens
:=
[]
*
api
.
Secret
{}
for
_
,
obj
:=
range
index
{
token
:=
obj
.
(
*
api
.
Secret
)
for
_
,
token
:=
range
tokens
{
if
token
.
Type
!=
api
.
SecretTypeServiceAccountToken
{
continue
}
if
serviceaccount
.
InternalIsServiceAccountToken
(
token
,
serviceAccount
)
{
tokens
=
append
(
tokens
,
token
)
...
...
plugin/pkg/admission/serviceaccount/admission_test.go
View file @
022bff7f
This diff is collapsed.
Click to expand it.
plugin/pkg/admission/storageclass/default/BUILD
View file @
022bff7f
...
...
@@ -16,15 +16,13 @@ go_library(
"//pkg/api:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/util:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/storage/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apiserver/pkg/admission",
"//vendor:k8s.io/client-go/tools/cache",
],
)
...
...
@@ -37,6 +35,8 @@ go_test(
"//pkg/api:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/util:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/controller:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apiserver/pkg/admission",
...
...
plugin/pkg/admission/storageclass/default/admission.go
View file @
022bff7f
...
...
@@ -23,15 +23,13 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apimachinery/pkg/labels"
admission
"k8s.io/apiserver/pkg/admission"
"k8s.io/client-go/tools/cache"
api
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/storage"
storageutil
"k8s.io/kubernetes/pkg/apis/storage/util"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
storagelisters
"k8s.io/kubernetes/pkg/client/listers/storage/internalversion"
kubeapiserveradmission
"k8s.io/kubernetes/pkg/kubeapiserver/admission"
)
...
...
@@ -49,15 +47,12 @@ func init() {
// claimDefaulterPlugin holds state for and implements the admission plugin.
type
claimDefaulterPlugin
struct
{
*
admission
.
Handler
client
internalclientset
.
Interface
reflector
*
cache
.
Reflector
stopChan
chan
struct
{}
store
cache
.
Store
lister
storagelisters
.
StorageClassLister
}
var
_
admission
.
Interface
=
&
claimDefaulterPlugin
{}
var
_
=
kubeapiserveradmission
.
WantsIn
ternalClientSet
(
&
claimDefaulterPlugin
{})
var
_
=
kubeapiserveradmission
.
WantsIn
formerFactory
(
&
claimDefaulterPlugin
{})
// newPlugin creates a new admission plugin.
func
newPlugin
()
*
claimDefaulterPlugin
{
...
...
@@ -66,55 +61,20 @@ func newPlugin() *claimDefaulterPlugin {
}
}
func
(
a
*
claimDefaulterPlugin
)
SetInternalClientSet
(
client
internalclientset
.
Interface
)
{
a
.
client
=
client
a
.
store
=
cache
.
NewStore
(
cache
.
MetaNamespaceKeyFunc
)
a
.
reflector
=
cache
.
NewReflector
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
client
.
Storage
()
.
StorageClasses
()
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
client
.
Storage
()
.
StorageClasses
()
.
Watch
(
options
)
},
},
&
storage
.
StorageClass
{},
a
.
store
,
0
,
)
if
client
!=
nil
{
a
.
Run
()
}
func
(
a
*
claimDefaulterPlugin
)
SetInformerFactory
(
f
informers
.
SharedInformerFactory
)
{
informer
:=
f
.
Storage
()
.
InternalVersion
()
.
StorageClasses
()
a
.
lister
=
informer
.
Lister
()
a
.
SetReadyFunc
(
informer
.
Informer
()
.
HasSynced
)
}
// Validate ensures an authorizer is set.
func
(
a
*
claimDefaulterPlugin
)
Validate
()
error
{
if
a
.
client
==
nil
{
return
fmt
.
Errorf
(
"missing client"
)
}
if
a
.
reflector
==
nil
{
return
fmt
.
Errorf
(
"missing reflector"
)
}
if
a
.
store
==
nil
{
return
fmt
.
Errorf
(
"missing store"
)
if
a
.
lister
==
nil
{
return
fmt
.
Errorf
(
"missing lister"
)
}
return
nil
}
func
(
a
*
claimDefaulterPlugin
)
Run
()
{
if
a
.
stopChan
==
nil
{
a
.
stopChan
=
make
(
chan
struct
{})
}
a
.
reflector
.
RunUntil
(
a
.
stopChan
)
}
func
(
a
*
claimDefaulterPlugin
)
Stop
()
{
if
a
.
stopChan
!=
nil
{
close
(
a
.
stopChan
)
a
.
stopChan
=
nil
}
}
// Admit sets the default value of a PersistentVolumeClaim's storage class, in case the user did
// not provide a value.
//
...
...
@@ -143,7 +103,7 @@ func (c *claimDefaulterPlugin) Admit(a admission.Attributes) error {
glog
.
V
(
4
)
.
Infof
(
"no storage class for claim %s (generate: %s)"
,
pvc
.
Name
,
pvc
.
GenerateName
)
def
,
err
:=
getDefaultClass
(
c
.
store
)
def
,
err
:=
getDefaultClass
(
c
.
lister
)
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
}
...
...
@@ -161,13 +121,14 @@ func (c *claimDefaulterPlugin) Admit(a admission.Attributes) error {
}
// getDefaultClass returns the default StorageClass from the store, or nil.
func
getDefaultClass
(
store
cache
.
Store
)
(
*
storage
.
StorageClass
,
error
)
{
func
getDefaultClass
(
lister
storagelisters
.
StorageClassLister
)
(
*
storage
.
StorageClass
,
error
)
{
list
,
err
:=
lister
.
List
(
labels
.
Everything
())
if
err
!=
nil
{
return
nil
,
err
}
defaultClasses
:=
[]
*
storage
.
StorageClass
{}
for
_
,
c
:=
range
store
.
List
()
{
class
,
ok
:=
c
.
(
*
storage
.
StorageClass
)
if
!
ok
{
return
nil
,
errors
.
NewInternalError
(
fmt
.
Errorf
(
"error converting stored object to StorageClass: %v"
,
c
))
}
for
_
,
class
:=
range
list
{
if
storageutil
.
IsDefaultAnnotation
(
class
.
ObjectMeta
)
{
defaultClasses
=
append
(
defaultClasses
,
class
)
glog
.
V
(
4
)
.
Infof
(
"getDefaultClass added: %s"
,
class
.
Name
)
...
...
plugin/pkg/admission/storageclass/default/admission_test.go
View file @
022bff7f
...
...
@@ -26,6 +26,8 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/storage"
storageutil
"k8s.io/kubernetes/pkg/apis/storage/util"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
"k8s.io/kubernetes/pkg/controller"
)
func
TestAdmission
(
t
*
testing
.
T
)
{
...
...
@@ -193,9 +195,10 @@ func TestAdmission(t *testing.T) {
claim
:=
clone
.
(
*
api
.
PersistentVolumeClaim
)
ctrl
:=
newPlugin
()
ctrl
.
SetInternalClientSet
(
nil
)
informerFactory
:=
informers
.
NewSharedInformerFactory
(
nil
,
controller
.
NoResyncPeriodFunc
())
ctrl
.
SetInformerFactory
(
informerFactory
)
for
_
,
c
:=
range
test
.
classes
{
ctrl
.
store
.
Add
(
c
)
informerFactory
.
Storage
()
.
InternalVersion
()
.
StorageClasses
()
.
Informer
()
.
GetStore
()
.
Add
(
c
)
}
attrs
:=
admission
.
NewAttributesRecord
(
claim
,
// new object
...
...
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
View file @
022bff7f
...
...
@@ -310,7 +310,12 @@ func ClusterRoles() []rbac.ClusterRole {
"services"
,
"serviceaccounts"
,
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"list"
,
"watch"
)
.
Groups
(
extensionsGroup
)
.
Resources
(
"daemonsets"
,
"deployments"
,
"replicasets"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"list"
,
"watch"
)
.
Groups
(
extensionsGroup
)
.
Resources
(
"daemonsets"
,
"deployments"
,
"podsecuritypolicies"
,
"replicasets"
,
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"list"
,
"watch"
)
.
Groups
(
batchGroup
)
.
Resources
(
"jobs"
,
"cronjobs"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"list"
,
"watch"
)
.
Groups
(
appsGroup
)
.
Resources
(
"statefulsets"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"list"
,
"watch"
)
.
Groups
(
policyGroup
)
.
Resources
(
"poddisruptionbudgets"
)
.
RuleOrDie
(),
...
...
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml
View file @
022bff7f
...
...
@@ -489,6 +489,7 @@ items:
resources
:
-
daemonsets
-
deployments
-
podsecuritypolicies
-
replicasets
verbs
:
-
list
...
...
test/integration/quota/quota_test.go
View file @
022bff7f
...
...
@@ -39,6 +39,7 @@ import (
clientset
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
internalinformers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
"k8s.io/kubernetes/pkg/controller"
replicationcontroller
"k8s.io/kubernetes/pkg/controller/replication"
resourcequotacontroller
"k8s.io/kubernetes/pkg/controller/resourcequota"
...
...
@@ -73,6 +74,8 @@ func TestQuota(t *testing.T) {
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
admission
.
(
kubeadmission
.
WantsInternalClientSet
)
.
SetInternalClientSet
(
internalClientset
)
internalInformers
:=
internalinformers
.
NewSharedInformerFactory
(
internalClientset
,
controller
.
NoResyncPeriodFunc
())
admission
.
(
kubeadmission
.
WantsInformerFactory
)
.
SetInformerFactory
(
internalInformers
)
defer
close
(
admissionCh
)
masterConfig
:=
framework
.
NewIntegrationTestMasterConfig
()
...
...
@@ -113,6 +116,7 @@ func TestQuota(t *testing.T) {
ControllerFactory
:
resourcequotacontroller
.
NewReplenishmentControllerFactory
(
informers
),
}
go
resourcequotacontroller
.
NewResourceQuotaController
(
resourceQuotaControllerOptions
)
.
Run
(
2
,
controllerCh
)
internalInformers
.
Start
(
controllerCh
)
informers
.
Start
(
controllerCh
)
startTime
:=
time
.
Now
()
...
...
@@ -257,6 +261,8 @@ func TestQuotaLimitedResourceDenial(t *testing.T) {
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
admission
.
(
kubeadmission
.
WantsInternalClientSet
)
.
SetInternalClientSet
(
internalClientset
)
internalInformers
:=
internalinformers
.
NewSharedInformerFactory
(
internalClientset
,
controller
.
NoResyncPeriodFunc
())
admission
.
(
kubeadmission
.
WantsInformerFactory
)
.
SetInformerFactory
(
internalInformers
)
defer
close
(
admissionCh
)
masterConfig
:=
framework
.
NewIntegrationTestMasterConfig
()
...
...
@@ -295,6 +301,7 @@ func TestQuotaLimitedResourceDenial(t *testing.T) {
ControllerFactory
:
resourcequotacontroller
.
NewReplenishmentControllerFactory
(
informers
),
}
go
resourcequotacontroller
.
NewResourceQuotaController
(
resourceQuotaControllerOptions
)
.
Run
(
2
,
controllerCh
)
internalInformers
.
Start
(
controllerCh
)
informers
.
Start
(
controllerCh
)
// try to create a pod
...
...
test/integration/serviceaccount/service_account_test.go
View file @
022bff7f
...
...
@@ -48,6 +48,7 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
internalinformers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
"k8s.io/kubernetes/pkg/controller"
serviceaccountcontroller
"k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"
...
...
@@ -407,6 +408,8 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
// Set up admission plugin to auto-assign serviceaccounts to pods
serviceAccountAdmission
:=
serviceaccountadmission
.
NewServiceAccount
()
serviceAccountAdmission
.
SetInternalClientSet
(
internalRootClientset
)
internalInformers
:=
internalinformers
.
NewSharedInformerFactory
(
internalRootClientset
,
controller
.
NoResyncPeriodFunc
())
serviceAccountAdmission
.
SetInformerFactory
(
internalInformers
)
masterConfig
:=
framework
.
NewMasterConfig
()
masterConfig
.
GenericConfig
.
EnableIndex
=
true
...
...
@@ -428,13 +431,11 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
serviceaccountcontroller
.
DefaultServiceAccountsControllerOptions
(),
)
informers
.
Start
(
stopCh
)
internalInformers
.
Start
(
stopCh
)
go
serviceAccountController
.
Run
(
5
,
stopCh
)
// Start the admission plugin reflectors
serviceAccountAdmission
.
Run
()
stop
:=
func
()
{
close
(
stopCh
)
serviceAccountAdmission
.
Stop
()
apiServer
.
Close
()
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment