externalize psp admission controller

This commit is contained in:
yue9944882
2018-10-12 19:50:05 -04:00
parent 7de4c007f7
commit e2c61169b1
32 changed files with 196 additions and 151 deletions

View File

@@ -14,13 +14,11 @@ go_library(
"//pkg/apis/core:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/policy/internalversion:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/registry/rbac:go_default_library",
"//pkg/security/podsecuritypolicy:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
@@ -28,6 +26,8 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/listers/policy/v1beta1:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
],
)
@@ -39,14 +39,14 @@ go_test(
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/apis/core/v1: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",
"//pkg/security/podsecuritypolicy/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
@@ -55,6 +55,7 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
],

View File

@@ -24,6 +24,7 @@ import (
"github.com/golang/glog"
policyv1beta1 "k8s.io/api/policy/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -31,12 +32,11 @@ import (
genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/informers"
policylisters "k8s.io/client-go/listers/policy/v1beta1"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/policy"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
policylisters "k8s.io/kubernetes/pkg/client/listers/policy/internalversion"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
rbacregistry "k8s.io/kubernetes/pkg/registry/rbac"
psp "k8s.io/kubernetes/pkg/security/podsecuritypolicy"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
@@ -83,7 +83,7 @@ func (plugin *PodSecurityPolicyPlugin) ValidateInitialization() error {
var _ admission.MutationInterface = &PodSecurityPolicyPlugin{}
var _ admission.ValidationInterface = &PodSecurityPolicyPlugin{}
var _ genericadmissioninit.WantsAuthorizer = &PodSecurityPolicyPlugin{}
var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &PodSecurityPolicyPlugin{}
var _ genericadmissioninit.WantsExternalKubeInformerFactory = &PodSecurityPolicyPlugin{}
var auditKeyPrefix = strings.ToLower(PluginName) + "." + policy.GroupName + ".k8s.io"
// newPlugin creates a new PSP admission plugin.
@@ -95,8 +95,8 @@ func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *PodS
}
}
func (a *PodSecurityPolicyPlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
podSecurityPolicyInformer := f.Policy().InternalVersion().PodSecurityPolicies()
func (a *PodSecurityPolicyPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
podSecurityPolicyInformer := f.Policy().V1beta1().PodSecurityPolicies()
a.lister = podSecurityPolicyInformer.Lister()
a.SetReadyFunc(podSecurityPolicyInformer.Informer().HasSynced)
}
@@ -338,7 +338,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList
}
// createProvidersFromPolicies creates providers from the constraints supplied.
func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policy.PodSecurityPolicy, namespace string) ([]psp.Provider, []error) {
func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policyv1beta1.PodSecurityPolicy, namespace string) ([]psp.Provider, []error) {
var (
// collected providers
providers []psp.Provider

View File

@@ -25,6 +25,7 @@ import (
"github.com/stretchr/testify/assert"
"k8s.io/api/core/v1"
policy "k8s.io/api/policy/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
@@ -33,10 +34,10 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
"k8s.io/client-go/informers"
"k8s.io/kubernetes/pkg/api/legacyscheme"
kapi "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/policy"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/security/apparmor"
kpsp "k8s.io/kubernetes/pkg/security/podsecuritypolicy"
@@ -50,11 +51,11 @@ const defaultContainerName = "test-c"
// NewTestAdmission provides an admission plugin with test implementations of internal structs.
func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer) *PodSecurityPolicyPlugin {
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
store := informerFactory.Policy().InternalVersion().PodSecurityPolicies().Informer().GetStore()
store := informerFactory.Policy().V1beta1().PodSecurityPolicies().Informer().GetStore()
for _, psp := range psps {
store.Add(psp)
}
lister := informerFactory.Policy().InternalVersion().PodSecurityPolicies().Lister()
lister := informerFactory.Policy().V1beta1().PodSecurityPolicies().Lister()
if authz == nil {
authz = &TestAuthorizer{}
}
@@ -502,19 +503,19 @@ func TestAdmitCaps(t *testing.T) {
allowsFooInAllowed := restrictivePSP()
allowsFooInAllowed.Name = "allowCapInAllowed"
allowsFooInAllowed.Spec.AllowedCapabilities = []kapi.Capability{"foo"}
allowsFooInAllowed.Spec.AllowedCapabilities = []v1.Capability{"foo"}
allowsFooInRequired := restrictivePSP()
allowsFooInRequired.Name = "allowCapInRequired"
allowsFooInRequired.Spec.DefaultAddCapabilities = []kapi.Capability{"foo"}
allowsFooInRequired.Spec.DefaultAddCapabilities = []v1.Capability{"foo"}
requiresFooToBeDropped := restrictivePSP()
requiresFooToBeDropped.Name = "requireDrop"
requiresFooToBeDropped.Spec.RequiredDropCapabilities = []kapi.Capability{"foo"}
requiresFooToBeDropped.Spec.RequiredDropCapabilities = []v1.Capability{"foo"}
allowAllInAllowed := restrictivePSP()
allowAllInAllowed.Name = "allowAllCapsInAllowed"
allowAllInAllowed.Spec.AllowedCapabilities = []kapi.Capability{policy.AllowAllCapabilities}
allowAllInAllowed.Spec.AllowedCapabilities = []v1.Capability{policy.AllowAllCapabilities}
tc := map[string]struct {
pod *kapi.Pod
@@ -959,12 +960,18 @@ func TestAdmitSELinux(t *testing.T) {
mustRunAs := permissivePSP()
mustRunAs.Name = "mustRunAs"
mustRunAs.Spec.SELinux.Rule = policy.SELinuxStrategyMustRunAs
mustRunAs.Spec.SELinux.SELinuxOptions = &kapi.SELinuxOptions{}
mustRunAs.Spec.SELinux.SELinuxOptions = &v1.SELinuxOptions{}
mustRunAs.Spec.SELinux.SELinuxOptions.Level = "level"
mustRunAs.Spec.SELinux.SELinuxOptions.Role = "role"
mustRunAs.Spec.SELinux.SELinuxOptions.Type = "type"
mustRunAs.Spec.SELinux.SELinuxOptions.User = "user"
getInternalSEOptions := func(policy *policy.PodSecurityPolicy) *kapi.SELinuxOptions {
opt := kapi.SELinuxOptions{}
k8s_api_v1.Convert_v1_SELinuxOptions_To_core_SELinuxOptions(policy.Spec.SELinux.SELinuxOptions, &opt, nil)
return &opt
}
tests := map[string]struct {
pod *kapi.Pod
psps []*policy.PodSecurityPolicy
@@ -1047,7 +1054,7 @@ func TestAdmitSELinux(t *testing.T) {
psps: []*policy.PodSecurityPolicy{mustRunAs},
shouldPassAdmit: true,
shouldPassValidate: true,
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: mustRunAs.Spec.SELinux.SELinuxOptions},
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
expectedContainerSC: nil,
expectedPSP: mustRunAs.Name,
},
@@ -1059,7 +1066,7 @@ func TestAdmitSELinux(t *testing.T) {
psps: []*policy.PodSecurityPolicy{mustRunAs},
shouldPassAdmit: true,
shouldPassValidate: true,
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: mustRunAs.Spec.SELinux.SELinuxOptions},
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
expectedContainerSC: nil,
expectedPSP: mustRunAs.Name,
},
@@ -1071,7 +1078,7 @@ func TestAdmitSELinux(t *testing.T) {
psps: []*policy.PodSecurityPolicy{mustRunAs},
shouldPassAdmit: true,
shouldPassValidate: true,
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: mustRunAs.Spec.SELinux.SELinuxOptions},
expectedPodSC: &kapi.PodSecurityContext{SELinuxOptions: getInternalSEOptions(mustRunAs)},
expectedContainerSC: nil,
expectedPSP: mustRunAs.Name,
},
@@ -2337,12 +2344,14 @@ func TestPreferValidatedPSP(t *testing.T) {
}
func restrictivePSP() *policy.PodSecurityPolicy {
allowPrivilegeEscalation := false
return &policy.PodSecurityPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "restrictive",
Annotations: map[string]string{},
},
Spec: policy.PodSecurityPolicySpec{
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
RunAsUser: policy.RunAsUserStrategyOptions{
Rule: policy.RunAsUserStrategyMustRunAs,
Ranges: []policy.IDRange{
@@ -2357,7 +2366,7 @@ func restrictivePSP() *policy.PodSecurityPolicy {
},
SELinux: policy.SELinuxStrategyOptions{
Rule: policy.SELinuxStrategyMustRunAs,
SELinuxOptions: &kapi.SELinuxOptions{
SELinuxOptions: &v1.SELinuxOptions{
Level: "s9:z0,z1",
},
},
@@ -2378,19 +2387,20 @@ func restrictivePSP() *policy.PodSecurityPolicy {
}
func permissivePSP() *policy.PodSecurityPolicy {
allowPrivilegeEscalation := true
return &policy.PodSecurityPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "privileged",
Annotations: map[string]string{},
},
Spec: policy.PodSecurityPolicySpec{
AllowPrivilegeEscalation: true,
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
HostIPC: true,
HostNetwork: true,
HostPID: true,
HostPorts: []policy.HostPortRange{{Min: 0, Max: 65536}},
Volumes: []policy.FSType{policy.All},
AllowedCapabilities: []kapi.Capability{policy.AllowAllCapabilities},
AllowedCapabilities: []v1.Capability{policy.AllowAllCapabilities},
RunAsUser: policy.RunAsUserStrategyOptions{
Rule: policy.RunAsUserStrategyRunAsAny,
},