Unverified Commit b8eecd67 authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #69941 from miguelbernadi/fix-golint-issues-68026

Fix golint issues in plugin/pkg/admission
parents 6d70e7ff f47da8a7
...@@ -320,20 +320,10 @@ pkg/volume/testing ...@@ -320,20 +320,10 @@ pkg/volume/testing
pkg/volume/util/fs pkg/volume/util/fs
pkg/volume/util/volumepathhandler pkg/volume/util/volumepathhandler
pkg/volume/vsphere_volume pkg/volume/vsphere_volume
plugin/pkg/admission/antiaffinity
plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1 plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1
plugin/pkg/admission/limitranger plugin/pkg/admission/limitranger
plugin/pkg/admission/noderestriction
plugin/pkg/admission/podnodeselector
plugin/pkg/admission/podpreset
plugin/pkg/admission/podtolerationrestriction
plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1
plugin/pkg/admission/resourcequota
plugin/pkg/admission/resourcequota/apis/resourcequota
plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1 plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1
plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1 plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1
plugin/pkg/admission/security/podsecuritypolicy
plugin/pkg/admission/serviceaccount
plugin/pkg/auth/authorizer/node plugin/pkg/auth/authorizer/node
plugin/pkg/auth/authorizer/rbac plugin/pkg/auth/authorizer/rbac
plugin/pkg/auth/authorizer/rbac/bootstrappolicy plugin/pkg/auth/authorizer/rbac/bootstrappolicy
......
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
) )
// PluginName is a string with the name of the plugin
const PluginName = "LimitPodHardAntiAffinityTopology" const PluginName = "LimitPodHardAntiAffinityTopology"
// Register registers a plugin // Register registers a plugin
......
...@@ -14,15 +14,16 @@ See the License for the specific language governing permissions and ...@@ -14,15 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// LimitPodHardAntiAffinityTopology admission controller rejects any pod // Package antiaffinity provides the LimitPodHardAntiAffinityTopology
// that specifies "hard" (RequiredDuringScheduling) anti-affinity // admission controller. It rejects any pod that specifies "hard"
// with a TopologyKey other than v1.LabelHostname. // (RequiredDuringScheduling) anti-affinity with a TopologyKey other
// Because anti-affinity is symmetric, without this admission controller, // than v1.LabelHostname. Because anti-affinity is symmetric, without
// a user could maliciously or accidentally specify that their pod (once it has scheduled) // this admission controller, a user could maliciously or accidentally
// should block other pods from scheduling into the same zone or some other large topology, // specify that their pod (once it has scheduled) should block other
// essentially DoSing the cluster. // pods from scheduling into the same zone or some other large
// In the future we will address this problem more fully by using quota and priority, // topology, essentially DoSing the cluster. In the future we will
// but for now this admission controller provides a simple protection, // address this problem more fully by using quota and priority, but
// on the assumption that the only legitimate use of hard pod anti-affinity // for now this admission controller provides a simple protection, on
// is to exclude other pods from the same node. // the assumption that the only legitimate use of hard pod
// anti-affinity is to exclude other pods from the same node.
package antiaffinity // import "k8s.io/kubernetes/plugin/pkg/admission/antiaffinity" package antiaffinity // import "k8s.io/kubernetes/plugin/pkg/admission/antiaffinity"
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
var ( var (
// SchemeBuilder is the scheme builder with scheme init functions to run for this API package // SchemeBuilder is the scheme builder with scheme init functions to run for this API package
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// AddToScheme is a global function that registers this API group & version to a scheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = SchemeBuilder.AddToScheme AddToScheme = SchemeBuilder.AddToScheme
) )
......
...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha ...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha
var ( var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
) )
func init() { func init() {
......
...@@ -78,16 +78,19 @@ type liveLookupEntry struct { ...@@ -78,16 +78,19 @@ type liveLookupEntry struct {
items []*corev1.LimitRange items []*corev1.LimitRange
} }
// SetExternalKubeInformerFactory registers an informer factory into the LimitRanger
func (l *LimitRanger) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { func (l *LimitRanger) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
limitRangeInformer := f.Core().V1().LimitRanges() limitRangeInformer := f.Core().V1().LimitRanges()
l.SetReadyFunc(limitRangeInformer.Informer().HasSynced) l.SetReadyFunc(limitRangeInformer.Informer().HasSynced)
l.lister = limitRangeInformer.Lister() l.lister = limitRangeInformer.Lister()
} }
func (a *LimitRanger) SetExternalKubeClientSet(client kubernetes.Interface) { // SetExternalKubeClientSet registers the client into LimitRanger
a.client = client func (l *LimitRanger) SetExternalKubeClientSet(client kubernetes.Interface) {
l.client = client
} }
// ValidateInitialization verifies the LimitRanger object has been properly initialized
func (l *LimitRanger) ValidateInitialization() error { func (l *LimitRanger) ValidateInitialization() error {
if l.lister == nil { if l.lister == nil {
return fmt.Errorf("missing limitRange lister") return fmt.Errorf("missing limitRange lister")
...@@ -146,6 +149,8 @@ func (l *LimitRanger) runLimitFunc(a admission.Attributes, limitFn func(limitRan ...@@ -146,6 +149,8 @@ func (l *LimitRanger) runLimitFunc(a admission.Attributes, limitFn func(limitRan
return nil return nil
} }
// GetLimitRanges returns a LimitRange object with the items held in
// the indexer if available, or do alive lookup of the value.
func (l *LimitRanger) GetLimitRanges(a admission.Attributes) ([]*corev1.LimitRange, error) { func (l *LimitRanger) GetLimitRanges(a admission.Attributes) ([]*corev1.LimitRange, error) {
items, err := l.lister.LimitRanges(a.GetNamespace()).List(labels.Everything()) items, err := l.lister.LimitRanges(a.GetNamespace()).List(labels.Everything())
if err != nil { if err != nil {
...@@ -306,13 +311,13 @@ func minConstraint(limitType string, resourceName string, enforced resource.Quan ...@@ -306,13 +311,13 @@ func minConstraint(limitType string, resourceName string, enforced resource.Quan
observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced) observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced)
if !reqExists { if !reqExists {
return fmt.Errorf("minimum %s usage per %s is %s. No request is specified.", resourceName, limitType, enforced.String()) return fmt.Errorf("minimum %s usage per %s is %s. No request is specified", resourceName, limitType, enforced.String())
} }
if observedReqValue < enforcedValue { if observedReqValue < enforcedValue {
return fmt.Errorf("minimum %s usage per %s is %s, but request is %s.", resourceName, limitType, enforced.String(), req.String()) return fmt.Errorf("minimum %s usage per %s is %s, but request is %s", resourceName, limitType, enforced.String(), req.String())
} }
if limExists && (observedLimValue < enforcedValue) { if limExists && (observedLimValue < enforcedValue) {
return fmt.Errorf("minimum %s usage per %s is %s, but limit is %s.", resourceName, limitType, enforced.String(), lim.String()) return fmt.Errorf("minimum %s usage per %s is %s, but limit is %s", resourceName, limitType, enforced.String(), lim.String())
} }
return nil return nil
} }
...@@ -324,10 +329,10 @@ func maxRequestConstraint(limitType string, resourceName string, enforced resour ...@@ -324,10 +329,10 @@ func maxRequestConstraint(limitType string, resourceName string, enforced resour
observedReqValue, _, enforcedValue := requestLimitEnforcedValues(req, resource.Quantity{}, enforced) observedReqValue, _, enforcedValue := requestLimitEnforcedValues(req, resource.Quantity{}, enforced)
if !reqExists { if !reqExists {
return fmt.Errorf("maximum %s usage per %s is %s. No request is specified.", resourceName, limitType, enforced.String()) return fmt.Errorf("maximum %s usage per %s is %s. No request is specified", resourceName, limitType, enforced.String())
} }
if observedReqValue > enforcedValue { if observedReqValue > enforcedValue {
return fmt.Errorf("maximum %s usage per %s is %s, but request is %s.", resourceName, limitType, enforced.String(), req.String()) return fmt.Errorf("maximum %s usage per %s is %s, but request is %s", resourceName, limitType, enforced.String(), req.String())
} }
return nil return nil
} }
...@@ -339,13 +344,13 @@ func maxConstraint(limitType string, resourceName string, enforced resource.Quan ...@@ -339,13 +344,13 @@ func maxConstraint(limitType string, resourceName string, enforced resource.Quan
observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced) observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced)
if !limExists { if !limExists {
return fmt.Errorf("maximum %s usage per %s is %s. No limit is specified.", resourceName, limitType, enforced.String()) return fmt.Errorf("maximum %s usage per %s is %s. No limit is specified", resourceName, limitType, enforced.String())
} }
if observedLimValue > enforcedValue { if observedLimValue > enforcedValue {
return fmt.Errorf("maximum %s usage per %s is %s, but limit is %s.", resourceName, limitType, enforced.String(), lim.String()) return fmt.Errorf("maximum %s usage per %s is %s, but limit is %s", resourceName, limitType, enforced.String(), lim.String())
} }
if reqExists && (observedReqValue > enforcedValue) { if reqExists && (observedReqValue > enforcedValue) {
return fmt.Errorf("maximum %s usage per %s is %s, but request is %s.", resourceName, limitType, enforced.String(), req.String()) return fmt.Errorf("maximum %s usage per %s is %s, but request is %s", resourceName, limitType, enforced.String(), req.String())
} }
return nil return nil
} }
...@@ -357,10 +362,10 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced ...@@ -357,10 +362,10 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced
observedReqValue, observedLimValue, _ := requestLimitEnforcedValues(req, lim, enforced) observedReqValue, observedLimValue, _ := requestLimitEnforcedValues(req, lim, enforced)
if !reqExists || (observedReqValue == int64(0)) { if !reqExists || (observedReqValue == int64(0)) {
return fmt.Errorf("%s max limit to request ratio per %s is %s, but no request is specified or request is 0.", resourceName, limitType, enforced.String()) return fmt.Errorf("%s max limit to request ratio per %s is %s, but no request is specified or request is 0", resourceName, limitType, enforced.String())
} }
if !limExists || (observedLimValue == int64(0)) { if !limExists || (observedLimValue == int64(0)) {
return fmt.Errorf("%s max limit to request ratio per %s is %s, but no limit is specified or limit is 0.", resourceName, limitType, enforced.String()) return fmt.Errorf("%s max limit to request ratio per %s is %s, but no limit is specified or limit is 0", resourceName, limitType, enforced.String())
} }
observedRatio := float64(observedLimValue) / float64(observedReqValue) observedRatio := float64(observedLimValue) / float64(observedReqValue)
...@@ -372,7 +377,7 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced ...@@ -372,7 +377,7 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced
} }
if observedRatio > maxLimitRequestRatio { if observedRatio > maxLimitRequestRatio {
return fmt.Errorf("%s max limit to request ratio per %s is %s, but provided ratio is %f.", resourceName, limitType, enforced.String(), displayObservedRatio) return fmt.Errorf("%s max limit to request ratio per %s is %s, but provided ratio is %f", resourceName, limitType, enforced.String(), displayObservedRatio)
} }
return nil return nil
...@@ -423,9 +428,10 @@ type DefaultLimitRangerActions struct{} ...@@ -423,9 +428,10 @@ type DefaultLimitRangerActions struct{}
// ensure DefaultLimitRangerActions implements the LimitRangerActions interface. // ensure DefaultLimitRangerActions implements the LimitRangerActions interface.
var _ LimitRangerActions = &DefaultLimitRangerActions{} var _ LimitRangerActions = &DefaultLimitRangerActions{}
// Limit enforces resource requirements of incoming resources against enumerated constraints // MutateLimit enforces resource requirements of incoming resources
// on the LimitRange. It may modify the incoming object to apply default resource requirements // against enumerated constraints on the LimitRange. It may modify
// if not specified, and enumerated on the LimitRange // the incoming object to apply default resource requirements if not
// specified, and enumerated on the LimitRange
func (d *DefaultLimitRangerActions) MutateLimit(limitRange *corev1.LimitRange, resourceName string, obj runtime.Object) error { func (d *DefaultLimitRangerActions) MutateLimit(limitRange *corev1.LimitRange, resourceName string, obj runtime.Object) error {
switch resourceName { switch resourceName {
case "pods": case "pods":
...@@ -434,9 +440,9 @@ func (d *DefaultLimitRangerActions) MutateLimit(limitRange *corev1.LimitRange, r ...@@ -434,9 +440,9 @@ func (d *DefaultLimitRangerActions) MutateLimit(limitRange *corev1.LimitRange, r
return nil return nil
} }
// Limit enforces resource requirements of incoming resources against enumerated constraints // ValidateLimit verifies the resource requirements of incoming
// on the LimitRange. It may modify the incoming object to apply default resource requirements // resources against enumerated constraints on the LimitRange are
// if not specified, and enumerated on the LimitRange // valid
func (d *DefaultLimitRangerActions) ValidateLimit(limitRange *corev1.LimitRange, resourceName string, obj runtime.Object) error { func (d *DefaultLimitRangerActions) ValidateLimit(limitRange *corev1.LimitRange, resourceName string, obj runtime.Object) error {
switch resourceName { switch resourceName {
case "pods": case "pods":
......
...@@ -656,42 +656,42 @@ func TestPodLimitFuncApplyDefault(t *testing.T) { ...@@ -656,42 +656,42 @@ func TestPodLimitFuncApplyDefault(t *testing.T) {
for i := range testPod.Spec.Containers { for i := range testPod.Spec.Containers {
container := testPod.Spec.Containers[i] container := testPod.Spec.Containers[i]
limitMemory := container.Resources.Limits.Memory().String() limitMemory := container.Resources.Limits.Memory().String()
limitCpu := container.Resources.Limits.Cpu().String() limitCPU := container.Resources.Limits.Cpu().String()
requestMemory := container.Resources.Requests.Memory().String() requestMemory := container.Resources.Requests.Memory().String()
requestCpu := container.Resources.Requests.Cpu().String() requestCPU := container.Resources.Requests.Cpu().String()
if limitMemory != "10Mi" { if limitMemory != "10Mi" {
t.Errorf("Unexpected limit memory value %s", limitMemory) t.Errorf("Unexpected limit memory value %s", limitMemory)
} }
if limitCpu != "75m" { if limitCPU != "75m" {
t.Errorf("Unexpected limit cpu value %s", limitCpu) t.Errorf("Unexpected limit cpu value %s", limitCPU)
} }
if requestMemory != "5Mi" { if requestMemory != "5Mi" {
t.Errorf("Unexpected request memory value %s", requestMemory) t.Errorf("Unexpected request memory value %s", requestMemory)
} }
if requestCpu != "50m" { if requestCPU != "50m" {
t.Errorf("Unexpected request cpu value %s", requestCpu) t.Errorf("Unexpected request cpu value %s", requestCPU)
} }
} }
for i := range testPod.Spec.InitContainers { for i := range testPod.Spec.InitContainers {
container := testPod.Spec.InitContainers[i] container := testPod.Spec.InitContainers[i]
limitMemory := container.Resources.Limits.Memory().String() limitMemory := container.Resources.Limits.Memory().String()
limitCpu := container.Resources.Limits.Cpu().String() limitCPU := container.Resources.Limits.Cpu().String()
requestMemory := container.Resources.Requests.Memory().String() requestMemory := container.Resources.Requests.Memory().String()
requestCpu := container.Resources.Requests.Cpu().String() requestCPU := container.Resources.Requests.Cpu().String()
if limitMemory != "10Mi" { if limitMemory != "10Mi" {
t.Errorf("Unexpected limit memory value %s", limitMemory) t.Errorf("Unexpected limit memory value %s", limitMemory)
} }
if limitCpu != "75m" { if limitCPU != "75m" {
t.Errorf("Unexpected limit cpu value %s", limitCpu) t.Errorf("Unexpected limit cpu value %s", limitCPU)
} }
if requestMemory != "5Mi" { if requestMemory != "5Mi" {
t.Errorf("Unexpected request memory value %s", requestMemory) t.Errorf("Unexpected request memory value %s", requestMemory)
} }
if requestCpu != "50m" { if requestCPU != "50m" {
t.Errorf("Unexpected request cpu value %s", requestCpu) t.Errorf("Unexpected request cpu value %s", requestCPU)
} }
} }
} }
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
) )
// LimitRangerActions is an interface defining actions to be carried over ranges to identify and manipulate their limits
type LimitRangerActions interface { type LimitRangerActions interface {
// MutateLimit is a pluggable function to set limits on the object. // MutateLimit is a pluggable function to set limits on the object.
MutateLimit(limitRange *corev1.LimitRange, kind string, obj runtime.Object) error MutateLimit(limitRange *corev1.LimitRange, kind string, obj runtime.Object) error
......
...@@ -36,10 +36,12 @@ import ( ...@@ -36,10 +36,12 @@ import (
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
) )
// The annotation key scheduler.alpha.kubernetes.io/node-selector is for assigning // NamespaceNodeSelectors is for assigning node selectors labels to
// node selectors labels to namespaces // namespaces. Default value is the annotation key
// scheduler.alpha.kubernetes.io/node-selector
var NamespaceNodeSelectors = []string{"scheduler.alpha.kubernetes.io/node-selector"} var NamespaceNodeSelectors = []string{"scheduler.alpha.kubernetes.io/node-selector"}
// PluginName is a string with the name of the plugin
const PluginName = "PodNodeSelector" const PluginName = "PodNodeSelector"
// Register registers a plugin // Register registers a plugin
...@@ -52,8 +54,8 @@ func Register(plugins *admission.Plugins) { ...@@ -52,8 +54,8 @@ func Register(plugins *admission.Plugins) {
}) })
} }
// podNodeSelector is an implementation of admission.Interface. // Plugin is an implementation of admission.Interface.
type podNodeSelector struct { type Plugin struct {
*admission.Handler *admission.Handler
client kubernetes.Interface client kubernetes.Interface
namespaceLister corev1listers.NamespaceLister namespaceLister corev1listers.NamespaceLister
...@@ -61,8 +63,8 @@ type podNodeSelector struct { ...@@ -61,8 +63,8 @@ type podNodeSelector struct {
clusterNodeSelectors map[string]string clusterNodeSelectors map[string]string
} }
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podNodeSelector{}) var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{})
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podNodeSelector{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
type pluginConfig struct { type pluginConfig struct {
PodNodeSelectorPluginConfig map[string]string PodNodeSelectorPluginConfig map[string]string
...@@ -94,7 +96,7 @@ func readConfig(config io.Reader) *pluginConfig { ...@@ -94,7 +96,7 @@ func readConfig(config io.Reader) *pluginConfig {
} }
// Admit enforces that pod and its namespace node label selectors matches at least a node in the cluster. // Admit enforces that pod and its namespace node label selectors matches at least a node in the cluster.
func (p *podNodeSelector) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -121,7 +123,7 @@ func (p *podNodeSelector) Admit(a admission.Attributes, o admission.ObjectInterf ...@@ -121,7 +123,7 @@ func (p *podNodeSelector) Admit(a admission.Attributes, o admission.ObjectInterf
} }
// Validate ensures that the pod node selector is allowed // Validate ensures that the pod node selector is allowed
func (p *podNodeSelector) Validate(a admission.Attributes, o admission.ObjectInterfaces) error { func (p *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -152,7 +154,7 @@ func (p *podNodeSelector) Validate(a admission.Attributes, o admission.ObjectInt ...@@ -152,7 +154,7 @@ func (p *podNodeSelector) Validate(a admission.Attributes, o admission.ObjectInt
return nil return nil
} }
func (p *podNodeSelector) getNamespaceNodeSelectorMap(namespaceName string) (labels.Set, error) { func (p *Plugin) getNamespaceNodeSelectorMap(namespaceName string) (labels.Set, error) {
namespace, err := p.namespaceLister.Get(namespaceName) namespace, err := p.namespaceLister.Get(namespaceName)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
namespace, err = p.defaultGetNamespace(namespaceName) namespace, err = p.defaultGetNamespace(namespaceName)
...@@ -188,24 +190,28 @@ func shouldIgnore(a admission.Attributes) bool { ...@@ -188,24 +190,28 @@ func shouldIgnore(a admission.Attributes) bool {
return false return false
} }
func NewPodNodeSelector(clusterNodeSelectors map[string]string) *podNodeSelector { // NewPodNodeSelector initializes a podNodeSelector
return &podNodeSelector{ func NewPodNodeSelector(clusterNodeSelectors map[string]string) *Plugin {
return &Plugin{
Handler: admission.NewHandler(admission.Create), Handler: admission.NewHandler(admission.Create),
clusterNodeSelectors: clusterNodeSelectors, clusterNodeSelectors: clusterNodeSelectors,
} }
} }
func (a *podNodeSelector) SetExternalKubeClientSet(client kubernetes.Interface) { // SetExternalKubeClientSet sets the plugin's client
a.client = client func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.client = client
} }
func (p *podNodeSelector) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { // SetExternalKubeInformerFactory configures the plugin's informer factory
func (p *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
namespaceInformer := f.Core().V1().Namespaces() namespaceInformer := f.Core().V1().Namespaces()
p.namespaceLister = namespaceInformer.Lister() p.namespaceLister = namespaceInformer.Lister()
p.SetReadyFunc(namespaceInformer.Informer().HasSynced) p.SetReadyFunc(namespaceInformer.Informer().HasSynced)
} }
func (p *podNodeSelector) ValidateInitialization() error { // ValidateInitialization verifies the object has been properly initialized
func (p *Plugin) ValidateInitialization() error {
if p.namespaceLister == nil { if p.namespaceLister == nil {
return fmt.Errorf("missing namespaceLister") return fmt.Errorf("missing namespaceLister")
} }
...@@ -215,7 +221,7 @@ func (p *podNodeSelector) ValidateInitialization() error { ...@@ -215,7 +221,7 @@ func (p *podNodeSelector) ValidateInitialization() error {
return nil return nil
} }
func (p *podNodeSelector) defaultGetNamespace(name string) (*corev1.Namespace, error) { func (p *Plugin) defaultGetNamespace(name string) (*corev1.Namespace, error) {
namespace, err := p.client.CoreV1().Namespaces().Get(name, metav1.GetOptions{}) namespace, err := p.client.CoreV1().Namespaces().Get(name, metav1.GetOptions{})
if err != nil { if err != nil {
return nil, fmt.Errorf("namespace %s does not exist", name) return nil, fmt.Errorf("namespace %s does not exist", name)
...@@ -223,7 +229,7 @@ func (p *podNodeSelector) defaultGetNamespace(name string) (*corev1.Namespace, e ...@@ -223,7 +229,7 @@ func (p *podNodeSelector) defaultGetNamespace(name string) (*corev1.Namespace, e
return namespace, nil return namespace, nil
} }
func (p *podNodeSelector) getNodeSelectorMap(namespace *corev1.Namespace) (labels.Set, error) { func (p *Plugin) getNodeSelectorMap(namespace *corev1.Namespace) (labels.Set, error) {
selector := labels.Set{} selector := labels.Set{}
labelsMap := labels.Set{} labelsMap := labels.Set{}
var err error var err error
......
...@@ -194,7 +194,7 @@ func TestHandles(t *testing.T) { ...@@ -194,7 +194,7 @@ func TestHandles(t *testing.T) {
} }
// newHandlerForTest returns the admission controller configured for testing. // newHandlerForTest returns the admission controller configured for testing.
func newHandlerForTest(c kubernetes.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) { func newHandlerForTest(c kubernetes.Interface) (*Plugin, informers.SharedInformerFactory, error) {
f := informers.NewSharedInformerFactory(c, 5*time.Minute) f := informers.NewSharedInformerFactory(c, 5*time.Minute)
handler := NewPodNodeSelector(nil) handler := NewPodNodeSelector(nil)
pluginInitializer := genericadmissioninitializer.New(c, f, nil) pluginInitializer := genericadmissioninitializer.New(c, f, nil)
......
...@@ -40,7 +40,8 @@ import ( ...@@ -40,7 +40,8 @@ import (
const ( const (
annotationPrefix = "podpreset.admission.kubernetes.io" annotationPrefix = "podpreset.admission.kubernetes.io"
PluginName = "PodPreset" // PluginName is a string with the name of the plugin
PluginName = "PodPreset"
) )
// Register registers a plugin // Register registers a plugin
...@@ -50,47 +51,50 @@ func Register(plugins *admission.Plugins) { ...@@ -50,47 +51,50 @@ func Register(plugins *admission.Plugins) {
}) })
} }
// podPresetPlugin is an implementation of admission.Interface. // Plugin is an implementation of admission.Interface.
type podPresetPlugin struct { type Plugin struct {
*admission.Handler *admission.Handler
client kubernetes.Interface client kubernetes.Interface
lister settingsv1alpha1listers.PodPresetLister lister settingsv1alpha1listers.PodPresetLister
} }
var _ admission.MutationInterface = &podPresetPlugin{} var _ admission.MutationInterface = &Plugin{}
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podPresetPlugin{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podPresetPlugin{}) var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{})
// NewPlugin creates a new pod preset admission plugin. // NewPlugin creates a new pod preset admission plugin.
func NewPlugin() *podPresetPlugin { func NewPlugin() *Plugin {
return &podPresetPlugin{ return &Plugin{
Handler: admission.NewHandler(admission.Create, admission.Update), Handler: admission.NewHandler(admission.Create, admission.Update),
} }
} }
func (plugin *podPresetPlugin) ValidateInitialization() error { // ValidateInitialization validates the Plugin was initialized properly
if plugin.client == nil { func (p *Plugin) ValidateInitialization() error {
if p.client == nil {
return fmt.Errorf("%s requires a client", PluginName) return fmt.Errorf("%s requires a client", PluginName)
} }
if plugin.lister == nil { if p.lister == nil {
return fmt.Errorf("%s requires a lister", PluginName) return fmt.Errorf("%s requires a lister", PluginName)
} }
return nil return nil
} }
func (a *podPresetPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { // SetExternalKubeClientSet registers the client into Plugin
a.client = client func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.client = client
} }
func (a *podPresetPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { // SetExternalKubeInformerFactory registers an informer factory into Plugin
func (p *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
podPresetInformer := f.Settings().V1alpha1().PodPresets() podPresetInformer := f.Settings().V1alpha1().PodPresets()
a.lister = podPresetInformer.Lister() p.lister = podPresetInformer.Lister()
a.SetReadyFunc(podPresetInformer.Informer().HasSynced) p.SetReadyFunc(podPresetInformer.Informer().HasSynced)
} }
// Admit injects a pod with the specific fields for each pod preset it matches. // Admit injects a pod with the specific fields for each pod preset it matches.
func (c *podPresetPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
// Ignore all calls to subresources or resources other than pods. // Ignore all calls to subresources or resources other than pods.
// Ignore all operations other than CREATE. // Ignore all operations other than CREATE.
if len(a.GetSubresource()) != 0 || a.GetResource().GroupResource() != api.Resource("pods") || a.GetOperation() != admission.Create { if len(a.GetSubresource()) != 0 || a.GetResource().GroupResource() != api.Resource("pods") || a.GetOperation() != admission.Create {
...@@ -114,7 +118,7 @@ func (c *podPresetPlugin) Admit(a admission.Attributes, o admission.ObjectInterf ...@@ -114,7 +118,7 @@ func (c *podPresetPlugin) Admit(a admission.Attributes, o admission.ObjectInterf
} }
} }
list, err := c.lister.PodPresets(a.GetNamespace()).List(labels.Everything()) list, err := p.lister.PodPresets(a.GetNamespace()).List(labels.Everything())
if err != nil { if err != nil {
return fmt.Errorf("listing pod presets failed: %v", err) return fmt.Errorf("listing pod presets failed: %v", err)
} }
......
...@@ -401,7 +401,7 @@ func NewTestAdmission(lister settingsv1alpha1listers.PodPresetLister, objects .. ...@@ -401,7 +401,7 @@ func NewTestAdmission(lister settingsv1alpha1listers.PodPresetLister, objects ..
// Build a test client that the admission plugin can use to look up the service account missing from its cache // Build a test client that the admission plugin can use to look up the service account missing from its cache
client := fake.NewSimpleClientset(objects...) client := fake.NewSimpleClientset(objects...)
return &podPresetPlugin{ return &Plugin{
client: client, client: client,
Handler: kadmission.NewHandler(kadmission.Create), Handler: kadmission.NewHandler(kadmission.Create),
lister: lister, lister: lister,
......
...@@ -35,6 +35,7 @@ go_library( ...@@ -35,6 +35,7 @@ go_library(
srcs = [ srcs = [
"admission.go", "admission.go",
"config.go", "config.go",
"doc.go",
], ],
importpath = "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction", importpath = "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction",
deps = [ deps = [
......
...@@ -39,6 +39,7 @@ import ( ...@@ -39,6 +39,7 @@ import (
pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction" pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction"
) )
// PluginName is a string with the name of the plugin
const PluginName = "PodTolerationRestriction" const PluginName = "PodTolerationRestriction"
// Register registers a plugin // Register registers a plugin
...@@ -58,29 +59,21 @@ const ( ...@@ -58,29 +59,21 @@ const (
NSWLTolerations string = "scheduler.alpha.kubernetes.io/tolerationsWhitelist" NSWLTolerations string = "scheduler.alpha.kubernetes.io/tolerationsWhitelist"
) )
var _ admission.MutationInterface = &podTolerationsPlugin{} var _ admission.MutationInterface = &Plugin{}
var _ admission.ValidationInterface = &podTolerationsPlugin{} var _ admission.ValidationInterface = &Plugin{}
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podTolerationsPlugin{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podTolerationsPlugin{}) var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{})
type podTolerationsPlugin struct { // Plugin contains the client used by the admission controller
type Plugin struct {
*admission.Handler *admission.Handler
client kubernetes.Interface client kubernetes.Interface
namespaceLister corev1listers.NamespaceLister namespaceLister corev1listers.NamespaceLister
pluginConfig *pluginapi.Configuration pluginConfig *pluginapi.Configuration
} }
// This plugin first verifies any conflict between a pod's tolerations and // Admit checks the admission policy and triggers corresponding actions
// its namespace's tolerations, and rejects the pod if there's a conflict. func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
// If there's no conflict, the pod's tolerations are merged with its namespace's
// toleration. Resulting pod's tolerations are verified against its namespace's
// whitelist of tolerations. If the verification is successful, the pod is admitted
// otherwise rejected. If a namespace does not have associated default or whitelist
// of tolerations, then cluster level default or whitelist of tolerations are used
// instead if specified. Tolerations to a namespace are assigned via
// scheduler.alpha.kubernetes.io/defaultTolerations and scheduler.alpha.kubernetes.io/tolerationsWhitelist
// annotations keys.
func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -136,7 +129,9 @@ func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectI ...@@ -136,7 +129,9 @@ func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectI
pod.Spec.Tolerations = tolerations.MergeTolerations(finalTolerations, []api.Toleration{}) pod.Spec.Tolerations = tolerations.MergeTolerations(finalTolerations, []api.Toleration{})
return p.Validate(a, o) return p.Validate(a, o)
} }
func (p *podTolerationsPlugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
// Validate we can obtain a whitelist of tolerations
func (p *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -190,25 +185,29 @@ func shouldIgnore(a admission.Attributes) bool { ...@@ -190,25 +185,29 @@ func shouldIgnore(a admission.Attributes) bool {
return false return false
} }
func NewPodTolerationsPlugin(pluginConfig *pluginapi.Configuration) *podTolerationsPlugin { // NewPodTolerationsPlugin initializes a Plugin
return &podTolerationsPlugin{ func NewPodTolerationsPlugin(pluginConfig *pluginapi.Configuration) *Plugin {
return &Plugin{
Handler: admission.NewHandler(admission.Create, admission.Update), Handler: admission.NewHandler(admission.Create, admission.Update),
pluginConfig: pluginConfig, pluginConfig: pluginConfig,
} }
} }
func (a *podTolerationsPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { // SetExternalKubeClientSet sets th client
a.client = client func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.client = client
} }
func (p *podTolerationsPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { // SetExternalKubeInformerFactory initializes the Informer Factory
func (p *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
namespaceInformer := f.Core().V1().Namespaces() namespaceInformer := f.Core().V1().Namespaces()
p.namespaceLister = namespaceInformer.Lister() p.namespaceLister = namespaceInformer.Lister()
p.SetReadyFunc(namespaceInformer.Informer().HasSynced) p.SetReadyFunc(namespaceInformer.Informer().HasSynced)
} }
func (p *podTolerationsPlugin) ValidateInitialization() error { // ValidateInitialization checks the object is properly initialized
func (p *Plugin) ValidateInitialization() error {
if p.namespaceLister == nil { if p.namespaceLister == nil {
return fmt.Errorf("missing namespaceLister") return fmt.Errorf("missing namespaceLister")
} }
...@@ -219,7 +218,7 @@ func (p *podTolerationsPlugin) ValidateInitialization() error { ...@@ -219,7 +218,7 @@ func (p *podTolerationsPlugin) ValidateInitialization() error {
} }
// in exceptional cases, this can result in two live calls, but once the cache catches up, that will stop. // in exceptional cases, this can result in two live calls, but once the cache catches up, that will stop.
func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, error) { func (p *Plugin) getNamespace(nsName string) (*corev1.Namespace, error) {
namespace, err := p.namespaceLister.Get(nsName) namespace, err := p.namespaceLister.Get(nsName)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
// in case of latency in our caches, make a call direct to storage to verify that it truly exists or not // in case of latency in our caches, make a call direct to storage to verify that it truly exists or not
...@@ -237,7 +236,7 @@ func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, e ...@@ -237,7 +236,7 @@ func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, e
return namespace, nil return namespace, nil
} }
func (p *podTolerationsPlugin) getNamespaceDefaultTolerations(nsName string) ([]api.Toleration, error) { func (p *Plugin) getNamespaceDefaultTolerations(nsName string) ([]api.Toleration, error) {
ns, err := p.getNamespace(nsName) ns, err := p.getNamespace(nsName)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -245,7 +244,7 @@ func (p *podTolerationsPlugin) getNamespaceDefaultTolerations(nsName string) ([] ...@@ -245,7 +244,7 @@ func (p *podTolerationsPlugin) getNamespaceDefaultTolerations(nsName string) ([]
return extractNSTolerations(ns, NSDefaultTolerations) return extractNSTolerations(ns, NSDefaultTolerations)
} }
func (p *podTolerationsPlugin) getNamespaceTolerationsWhitelist(nsName string) ([]api.Toleration, error) { func (p *Plugin) getNamespaceTolerationsWhitelist(nsName string) ([]api.Toleration, error) {
ns, err := p.getNamespace(nsName) ns, err := p.getNamespace(nsName)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -350,7 +350,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { ...@@ -350,7 +350,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
} }
// newHandlerForTest returns the admission controller configured for testing. // newHandlerForTest returns the admission controller configured for testing.
func newHandlerForTest(c kubernetes.Interface) (*podTolerationsPlugin, informers.SharedInformerFactory, error) { func newHandlerForTest(c kubernetes.Interface) (*Plugin, informers.SharedInformerFactory, error) {
f := informers.NewSharedInformerFactory(c, 5*time.Minute) f := informers.NewSharedInformerFactory(c, 5*time.Minute)
pluginConfig, err := loadConfiguration(nil) pluginConfig, err := loadConfiguration(nil)
// must not fail // must not fail
......
...@@ -30,7 +30,7 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime. ...@@ -30,7 +30,7 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.
var ( var (
// SchemeBuilder is the scheme builder with scheme init functions to run for this API package // SchemeBuilder is the scheme builder with scheme init functions to run for this API package
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// AddToScheme is a global function that registers this API group & version to a scheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = SchemeBuilder.AddToScheme AddToScheme = SchemeBuilder.AddToScheme
) )
......
...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha ...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha
var ( var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
) )
func init() { func init() {
......
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package podtolerationrestriction is a plugin that first verifies
// any conflict between a pod's tolerations and its namespace's
// tolerations, and rejects the pod if there's a conflict. If there's
// no conflict, the pod's tolerations are merged with its namespace's
// toleration. Resulting pod's tolerations are verified against its
// namespace's whitelist of tolerations. If the verification is
// successful, the pod is admitted otherwise rejected. If a namespace
// does not have associated default or whitelist of tolerations, then
// cluster level default or whitelist of tolerations are used instead
// if specified. Tolerations to a namespace are assigned via
// scheduler.alpha.kubernetes.io/defaultTolerations and
// scheduler.alpha.kubernetes.io/tolerationsWhitelist annotations
// keys.
package podtolerationrestriction // import "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction"
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation" "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation"
) )
// PluginName is a string with the name of the plugin
const PluginName = "ResourceQuota" const PluginName = "ResourceQuota"
// Register registers a plugin // Register registers a plugin
...@@ -93,14 +94,17 @@ func NewResourceQuota(config *resourcequotaapi.Configuration, numEvaluators int, ...@@ -93,14 +94,17 @@ func NewResourceQuota(config *resourcequotaapi.Configuration, numEvaluators int,
}, nil }, nil
} }
// SetExternalKubeClientSet registers the client into QuotaAdmission
func (a *QuotaAdmission) SetExternalKubeClientSet(client kubernetes.Interface) { func (a *QuotaAdmission) SetExternalKubeClientSet(client kubernetes.Interface) {
a.quotaAccessor.client = client a.quotaAccessor.client = client
} }
// SetExternalKubeInformerFactory registers an informer factory into QuotaAdmission
func (a *QuotaAdmission) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { func (a *QuotaAdmission) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
a.quotaAccessor.lister = f.Core().V1().ResourceQuotas().Lister() a.quotaAccessor.lister = f.Core().V1().ResourceQuotas().Lister()
} }
// SetQuotaConfiguration assigns and initializes configuration and evaluator for QuotaAdmission
func (a *QuotaAdmission) SetQuotaConfiguration(c quota.Configuration) { func (a *QuotaAdmission) SetQuotaConfiguration(c quota.Configuration) {
a.quotaConfiguration = c a.quotaConfiguration = c
a.evaluator = NewQuotaEvaluator(a.quotaAccessor, a.quotaConfiguration.IgnoredResources(), generic.NewRegistry(a.quotaConfiguration.Evaluators()), nil, a.config, a.numEvaluators, a.stopCh) a.evaluator = NewQuotaEvaluator(a.quotaAccessor, a.quotaConfiguration.IgnoredResources(), generic.NewRegistry(a.quotaConfiguration.Evaluators()), nil, a.config, a.numEvaluators, a.stopCh)
......
...@@ -22,8 +22,10 @@ import ( ...@@ -22,8 +22,10 @@ import (
) )
var ( var (
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = SchemeBuilder.AddToScheme
) )
// GroupName is the group name use in this package // GroupName is the group name use in this package
......
...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha ...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha
var ( var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
) )
func init() { func init() {
......
...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1 ...@@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1
var ( var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder is a pointer used to call AddToScheme
SchemeBuilder runtime.SchemeBuilder SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme // AddToScheme is used to register the types to API encoding/decoding machinery
AddToScheme = localSchemeBuilder.AddToScheme
) )
func init() { func init() {
......
...@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and ...@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// resourcequota enforces all incoming requests against any applied quota // Package resourcequota enforces all incoming requests against any applied quota
// in the namespace context of the request // in the namespace context of the request
package resourcequota // import "k8s.io/kubernetes/plugin/pkg/admission/resourcequota" package resourcequota // import "k8s.io/kubernetes/plugin/pkg/admission/resourcequota"
...@@ -43,9 +43,8 @@ import ( ...@@ -43,9 +43,8 @@ import (
"k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount"
) )
const ( // PluginName is a string with the name of the plugin
PluginName = "PodSecurityPolicy" const PluginName = "PodSecurityPolicy"
)
// Register registers a plugin // Register registers a plugin
func Register(plugins *admission.Plugins) { func Register(plugins *admission.Plugins) {
...@@ -55,8 +54,8 @@ func Register(plugins *admission.Plugins) { ...@@ -55,8 +54,8 @@ func Register(plugins *admission.Plugins) {
}) })
} }
// PodSecurityPolicyPlugin holds state for and implements the admission plugin. // Plugin holds state for and implements the admission plugin.
type PodSecurityPolicyPlugin struct { type Plugin struct {
*admission.Handler *admission.Handler
strategyFactory psp.StrategyFactory strategyFactory psp.StrategyFactory
failOnNoPolicies bool failOnNoPolicies bool
...@@ -65,40 +64,41 @@ type PodSecurityPolicyPlugin struct { ...@@ -65,40 +64,41 @@ type PodSecurityPolicyPlugin struct {
} }
// SetAuthorizer sets the authorizer. // SetAuthorizer sets the authorizer.
func (plugin *PodSecurityPolicyPlugin) SetAuthorizer(authz authorizer.Authorizer) { func (p *Plugin) SetAuthorizer(authz authorizer.Authorizer) {
plugin.authz = authz p.authz = authz
} }
// ValidateInitialization ensures an authorizer is set. // ValidateInitialization ensures an authorizer is set.
func (plugin *PodSecurityPolicyPlugin) ValidateInitialization() error { func (p *Plugin) ValidateInitialization() error {
if plugin.authz == nil { if p.authz == nil {
return fmt.Errorf("%s requires an authorizer", PluginName) return fmt.Errorf("%s requires an authorizer", PluginName)
} }
if plugin.lister == nil { if p.lister == nil {
return fmt.Errorf("%s requires a lister", PluginName) return fmt.Errorf("%s requires a lister", PluginName)
} }
return nil return nil
} }
var _ admission.MutationInterface = &PodSecurityPolicyPlugin{} var _ admission.MutationInterface = &Plugin{}
var _ admission.ValidationInterface = &PodSecurityPolicyPlugin{} var _ admission.ValidationInterface = &Plugin{}
var _ genericadmissioninit.WantsAuthorizer = &PodSecurityPolicyPlugin{} var _ genericadmissioninit.WantsAuthorizer = &Plugin{}
var _ genericadmissioninit.WantsExternalKubeInformerFactory = &PodSecurityPolicyPlugin{} var _ genericadmissioninit.WantsExternalKubeInformerFactory = &Plugin{}
var auditKeyPrefix = strings.ToLower(PluginName) + "." + policy.GroupName + ".k8s.io" var auditKeyPrefix = strings.ToLower(PluginName) + "." + policy.GroupName + ".k8s.io"
// newPlugin creates a new PSP admission plugin. // newPlugin creates a new PSP admission plugin.
func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *PodSecurityPolicyPlugin { func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *Plugin {
return &PodSecurityPolicyPlugin{ return &Plugin{
Handler: admission.NewHandler(admission.Create, admission.Update), Handler: admission.NewHandler(admission.Create, admission.Update),
strategyFactory: strategyFactory, strategyFactory: strategyFactory,
failOnNoPolicies: failOnNoPolicies, failOnNoPolicies: failOnNoPolicies,
} }
} }
func (a *PodSecurityPolicyPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { // SetExternalKubeInformerFactory registers an informer
func (p *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
podSecurityPolicyInformer := f.Policy().V1beta1().PodSecurityPolicies() podSecurityPolicyInformer := f.Policy().V1beta1().PodSecurityPolicies()
a.lister = podSecurityPolicyInformer.Lister() p.lister = podSecurityPolicyInformer.Lister()
a.SetReadyFunc(podSecurityPolicyInformer.Informer().HasSynced) p.SetReadyFunc(podSecurityPolicyInformer.Informer().HasSynced)
} }
// Admit determines if the pod should be admitted based on the requested security context // Admit determines if the pod should be admitted based on the requested security context
...@@ -109,7 +109,7 @@ func (a *PodSecurityPolicyPlugin) SetExternalKubeInformerFactory(f informers.Sha ...@@ -109,7 +109,7 @@ func (a *PodSecurityPolicyPlugin) SetExternalKubeInformerFactory(f informers.Sha
// 3. Try to generate and validate a PSP with providers. If we find one then admit the pod // 3. Try to generate and validate a PSP with providers. If we find one then admit the pod
// with the validated PSP. If we don't find any reject the pod and give all errors from the // with the validated PSP. If we don't find any reject the pod and give all errors from the
// failed attempts. // failed attempts.
func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
if ignore, err := shouldIgnore(a); err != nil { if ignore, err := shouldIgnore(a); err != nil {
return err return err
} else if ignore { } else if ignore {
...@@ -125,7 +125,7 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.Obje ...@@ -125,7 +125,7 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.Obje
pod := a.GetObject().(*api.Pod) pod := a.GetObject().(*api.Pod)
// compute the context. Mutation is allowed. ValidatedPSPAnnotation is not taken into account. // compute the context. Mutation is allowed. ValidatedPSPAnnotation is not taken into account.
allowedPod, pspName, validationErrs, err := c.computeSecurityContext(a, pod, true, "") allowedPod, pspName, validationErrs, err := p.computeSecurityContext(a, pod, true, "")
if err != nil { if err != nil {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
} }
...@@ -149,7 +149,8 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.Obje ...@@ -149,7 +149,8 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.Obje
return admission.NewForbidden(a, fmt.Errorf("unable to validate against any pod security policy: %v", validationErrs)) return admission.NewForbidden(a, fmt.Errorf("unable to validate against any pod security policy: %v", validationErrs))
} }
func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error { // Validate verifies attributes against the PodSecurityPolicy
func (p *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
if ignore, err := shouldIgnore(a); err != nil { if ignore, err := shouldIgnore(a); err != nil {
return err return err
} else if ignore { } else if ignore {
...@@ -159,7 +160,7 @@ func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes, o admission.O ...@@ -159,7 +160,7 @@ func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes, o admission.O
pod := a.GetObject().(*api.Pod) pod := a.GetObject().(*api.Pod)
// compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up. // compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up.
allowedPod, pspName, validationErrs, err := c.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation]) allowedPod, pspName, validationErrs, err := p.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
if err != nil { if err != nil {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
} }
...@@ -205,7 +206,7 @@ func shouldIgnore(a admission.Attributes) (bool, error) { ...@@ -205,7 +206,7 @@ func shouldIgnore(a admission.Attributes) (bool, error) {
// if there is a matching policy with the same security context as given, it will be reused. If there is no // if there is a matching policy with the same security context as given, it will be reused. If there is no
// matching policy the returned pod will be nil and the pspName empty. validatedPSPHint is the validated psp name // matching policy the returned pod will be nil and the pspName empty. validatedPSPHint is the validated psp name
// saved in kubernetes.io/psp annotation. This psp is usually the one we are looking for. // saved in kubernetes.io/psp annotation. This psp is usually the one we are looking for.
func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, specMutationAllowed bool, validatedPSPHint string) (*api.Pod, string, field.ErrorList, error) { func (p *Plugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, specMutationAllowed bool, validatedPSPHint string) (*api.Pod, string, field.ErrorList, error) {
// get all constraints that are usable by the user // get all constraints that are usable by the user
klog.V(4).Infof("getting pod security policies for pod %s (generate: %s)", pod.Name, pod.GenerateName) klog.V(4).Infof("getting pod security policies for pod %s (generate: %s)", pod.Name, pod.GenerateName)
var saInfo user.Info var saInfo user.Info
...@@ -213,14 +214,14 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, ...@@ -213,14 +214,14 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
saInfo = serviceaccount.UserInfo(a.GetNamespace(), pod.Spec.ServiceAccountName, "") saInfo = serviceaccount.UserInfo(a.GetNamespace(), pod.Spec.ServiceAccountName, "")
} }
policies, err := c.lister.List(labels.Everything()) policies, err := p.lister.List(labels.Everything())
if err != nil { if err != nil {
return nil, "", nil, err return nil, "", nil, err
} }
// if we have no policies and want to succeed then return. Otherwise we'll end up with no // if we have no policies and want to succeed then return. Otherwise we'll end up with no
// providers and fail with "unable to validate against any pod security policy" below. // providers and fail with "unable to validate against any pod security policy" below.
if len(policies) == 0 && !c.failOnNoPolicies { if len(policies) == 0 && !p.failOnNoPolicies {
return pod, "", nil, nil return pod, "", nil, nil
} }
...@@ -239,7 +240,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, ...@@ -239,7 +240,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
return strings.Compare(policies[i].Name, policies[j].Name) < 0 return strings.Compare(policies[i].Name, policies[j].Name) < 0
}) })
providers, errs := c.createProvidersFromPolicies(policies, pod.Namespace) providers, errs := p.createProvidersFromPolicies(policies, pod.Namespace)
for _, err := range errs { for _, err := range errs {
klog.V(4).Infof("provider creation error: %v", err) klog.V(4).Infof("provider creation error: %v", err)
} }
...@@ -269,7 +270,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, ...@@ -269,7 +270,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
continue continue
} }
if !isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), c.authz) { if !isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), p.authz) {
continue continue
} }
...@@ -293,7 +294,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, ...@@ -293,7 +294,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
// Pod is rejected. Filter the validation errors to only include errors from authorized PSPs. // Pod is rejected. Filter the validation errors to only include errors from authorized PSPs.
aggregate := field.ErrorList{} aggregate := field.ErrorList{}
for psp, errs := range validationErrs { for psp, errs := range validationErrs {
if isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), psp, c.authz) { if isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), psp, p.authz) {
aggregate = append(aggregate, errs...) aggregate = append(aggregate, errs...)
} }
} }
...@@ -317,7 +318,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList ...@@ -317,7 +318,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList
} }
// createProvidersFromPolicies creates providers from the constraints supplied. // createProvidersFromPolicies creates providers from the constraints supplied.
func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policyv1beta1.PodSecurityPolicy, namespace string) ([]psp.Provider, []error) { func (p *Plugin) createProvidersFromPolicies(psps []*policyv1beta1.PodSecurityPolicy, namespace string) ([]psp.Provider, []error) {
var ( var (
// collected providers // collected providers
providers []psp.Provider providers []psp.Provider
...@@ -326,7 +327,7 @@ func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policyv1be ...@@ -326,7 +327,7 @@ func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policyv1be
) )
for _, constraint := range psps { for _, constraint := range psps {
provider, err := psp.NewSimpleProvider(constraint, namespace, c.strategyFactory) provider, err := psp.NewSimpleProvider(constraint, namespace, p.strategyFactory)
if err != nil { if err != nil {
errs = append(errs, fmt.Errorf("error creating provider for PSP %s: %v", constraint.Name, err)) errs = append(errs, fmt.Errorf("error creating provider for PSP %s: %v", constraint.Name, err))
continue continue
......
...@@ -53,7 +53,7 @@ import ( ...@@ -53,7 +53,7 @@ import (
const defaultContainerName = "test-c" const defaultContainerName = "test-c"
// NewTestAdmission provides an admission plugin with test implementations of internal structs. // NewTestAdmission provides an admission plugin with test implementations of internal structs.
func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer) *PodSecurityPolicyPlugin { func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer) *Plugin {
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
store := informerFactory.Policy().V1beta1().PodSecurityPolicies().Informer().GetStore() store := informerFactory.Policy().V1beta1().PodSecurityPolicies().Informer().GetStore()
for _, psp := range psps { for _, psp := range psps {
...@@ -63,7 +63,7 @@ func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authori ...@@ -63,7 +63,7 @@ func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authori
if authz == nil { if authz == nil {
authz = &TestAuthorizer{} authz = &TestAuthorizer{}
} }
return &PodSecurityPolicyPlugin{ return &Plugin{
Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update), Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update),
strategyFactory: kpsp.NewSimpleStrategyFactory(), strategyFactory: kpsp.NewSimpleStrategyFactory(),
authz: authz, authz: authz,
...@@ -1963,7 +1963,7 @@ func TestCreateProvidersFromConstraints(t *testing.T) { ...@@ -1963,7 +1963,7 @@ func TestCreateProvidersFromConstraints(t *testing.T) {
} }
for k, v := range testCases { for k, v := range testCases {
admit := &PodSecurityPolicyPlugin{ admit := &Plugin{
Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update), Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update),
strategyFactory: kpsp.NewSimpleStrategyFactory(), strategyFactory: kpsp.NewSimpleStrategyFactory(),
} }
......
...@@ -52,6 +52,7 @@ const ( ...@@ -52,6 +52,7 @@ const (
// The value must be true to have this annotation take effect // The value must be true to have this annotation take effect
EnforceMountableSecretsAnnotation = "kubernetes.io/enforce-mountable-secrets" EnforceMountableSecretsAnnotation = "kubernetes.io/enforce-mountable-secrets"
// ServiceAccountVolumeName is the prefix name that will be added to volumes that mount ServiceAccount secrets
ServiceAccountVolumeName = "kube-api-access" ServiceAccountVolumeName = "kube-api-access"
// DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to. // DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to.
...@@ -70,9 +71,10 @@ func Register(plugins *admission.Plugins) { ...@@ -70,9 +71,10 @@ func Register(plugins *admission.Plugins) {
}) })
} }
var _ = admission.Interface(&serviceAccount{}) var _ = admission.Interface(&Plugin{})
type serviceAccount struct { // Plugin contains the client used by the admission controller
type Plugin struct {
*admission.Handler *admission.Handler
// LimitSecretReferences rejects pods that reference secrets their service accounts do not reference // LimitSecretReferences rejects pods that reference secrets their service accounts do not reference
...@@ -92,10 +94,10 @@ type serviceAccount struct { ...@@ -92,10 +94,10 @@ type serviceAccount struct {
featureGate featuregate.FeatureGate featureGate featuregate.FeatureGate
} }
var _ admission.MutationInterface = &serviceAccount{} var _ admission.MutationInterface = &Plugin{}
var _ admission.ValidationInterface = &serviceAccount{} var _ admission.ValidationInterface = &Plugin{}
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&serviceAccount{}) var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{})
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAccount{}) var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
// NewServiceAccount returns an admission.Interface implementation which limits admission of Pod CREATE requests based on the pod's 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" // 1. If the pod does not specify a ServiceAccount, it sets the pod's ServiceAccount to "default"
...@@ -103,8 +105,8 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAcc ...@@ -103,8 +105,8 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAcc
// 3. If LimitSecretReferences is true, it rejects the pod if the pod references Secret objects which the pod's ServiceAccount does not reference // 3. If LimitSecretReferences is true, it rejects the pod if the pod references Secret objects which the pod's ServiceAccount does not reference
// 4. If the pod does not contain any ImagePullSecrets, the ImagePullSecrets of the service account are added. // 4. If the pod does not contain any ImagePullSecrets, the ImagePullSecrets of the service account are added.
// 5. If MountServiceAccountToken is true, it adds a VolumeMount with the pod's ServiceAccount's api token secret to containers // 5. If MountServiceAccountToken is true, it adds a VolumeMount with the pod's ServiceAccount's api token secret to containers
func NewServiceAccount() *serviceAccount { func NewServiceAccount() *Plugin {
return &serviceAccount{ return &Plugin{
Handler: admission.NewHandler(admission.Create), Handler: admission.NewHandler(admission.Create),
// TODO: enable this once we've swept secret usage to account for adding secret references to service accounts // TODO: enable this once we've swept secret usage to account for adding secret references to service accounts
LimitSecretReferences: false, LimitSecretReferences: false,
...@@ -119,11 +121,13 @@ func NewServiceAccount() *serviceAccount { ...@@ -119,11 +121,13 @@ func NewServiceAccount() *serviceAccount {
} }
} }
func (s *serviceAccount) SetExternalKubeClientSet(cl kubernetes.Interface) { // SetExternalKubeClientSet sets the client for the plugin
func (s *Plugin) SetExternalKubeClientSet(cl kubernetes.Interface) {
s.client = cl s.client = cl
} }
func (s *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { // SetExternalKubeInformerFactory registers informers with the plugin
func (s *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
serviceAccountInformer := f.Core().V1().ServiceAccounts() serviceAccountInformer := f.Core().V1().ServiceAccounts()
s.serviceAccountLister = serviceAccountInformer.Lister() s.serviceAccountLister = serviceAccountInformer.Lister()
...@@ -136,7 +140,7 @@ func (s *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInform ...@@ -136,7 +140,7 @@ func (s *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInform
} }
// ValidateInitialization ensures an authorizer is set. // ValidateInitialization ensures an authorizer is set.
func (s *serviceAccount) ValidateInitialization() error { func (s *Plugin) ValidateInitialization() error {
if s.client == nil { if s.client == nil {
return fmt.Errorf("missing client") return fmt.Errorf("missing client")
} }
...@@ -149,7 +153,8 @@ func (s *serviceAccount) ValidateInitialization() error { ...@@ -149,7 +153,8 @@ func (s *serviceAccount) ValidateInitialization() error {
return nil return nil
} }
func (s *serviceAccount) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) { // Admit verifies if the pod should be admitted
func (s *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -190,7 +195,8 @@ func (s *serviceAccount) Admit(a admission.Attributes, o admission.ObjectInterfa ...@@ -190,7 +195,8 @@ func (s *serviceAccount) Admit(a admission.Attributes, o admission.ObjectInterfa
return s.Validate(a, o) return s.Validate(a, o)
} }
func (s *serviceAccount) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) { // Validate the data we obtained
func (s *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
if shouldIgnore(a) { if shouldIgnore(a) {
return nil return nil
} }
...@@ -271,7 +277,7 @@ func shouldAutomount(sa *corev1.ServiceAccount, pod *api.Pod) bool { ...@@ -271,7 +277,7 @@ func shouldAutomount(sa *corev1.ServiceAccount, pod *api.Pod) bool {
// enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account // enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account
// A global setting of true will override any flag set on the individual service account // A global setting of true will override any flag set on the individual service account
func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceAccount) bool { func (s *Plugin) enforceMountableSecrets(serviceAccount *corev1.ServiceAccount) bool {
if s.LimitSecretReferences { if s.LimitSecretReferences {
return true return true
} }
...@@ -285,7 +291,7 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceA ...@@ -285,7 +291,7 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceA
} }
// getServiceAccount returns the ServiceAccount for the given namespace and name if it exists // getServiceAccount returns the ServiceAccount for the given namespace and name if it exists
func (s *serviceAccount) getServiceAccount(namespace string, name string) (*corev1.ServiceAccount, error) { func (s *Plugin) getServiceAccount(namespace string, name string) (*corev1.ServiceAccount, error) {
serviceAccount, err := s.serviceAccountLister.ServiceAccounts(namespace).Get(name) serviceAccount, err := s.serviceAccountLister.ServiceAccounts(namespace).Get(name)
if err == nil { if err == nil {
return serviceAccount, nil return serviceAccount, nil
...@@ -318,7 +324,7 @@ func (s *serviceAccount) getServiceAccount(namespace string, name string) (*core ...@@ -318,7 +324,7 @@ func (s *serviceAccount) getServiceAccount(namespace string, name string) (*core
} }
// getReferencedServiceAccountToken returns the name of the first referenced secret which is a ServiceAccountToken for the service account // getReferencedServiceAccountToken returns the name of the first referenced secret which is a ServiceAccountToken for the service account
func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) { func (s *Plugin) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) {
if len(serviceAccount.Secrets) == 0 { if len(serviceAccount.Secrets) == 0 {
return "", nil return "", nil
} }
...@@ -343,7 +349,7 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1 ...@@ -343,7 +349,7 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1
} }
// getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount // getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount
func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceAccount) ([]*corev1.Secret, error) { func (s *Plugin) getServiceAccountTokens(serviceAccount *corev1.ServiceAccount) ([]*corev1.Secret, error) {
secrets, err := s.secretLister.Secrets(serviceAccount.Namespace).List(labels.Everything()) secrets, err := s.secretLister.Secrets(serviceAccount.Namespace).List(labels.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -363,7 +369,7 @@ func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceA ...@@ -363,7 +369,7 @@ func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceA
return tokens, nil return tokens, nil
} }
func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error { func (s *Plugin) limitSecretReferences(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
// Ensure all secrets the pod references are allowed by the service account // Ensure all secrets the pod references are allowed by the service account
mountableSecrets := sets.NewString() mountableSecrets := sets.NewString()
for _, s := range serviceAccount.Secrets { for _, s := range serviceAccount.Secrets {
...@@ -413,7 +419,7 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAcc ...@@ -413,7 +419,7 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAcc
return nil return nil
} }
func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error { func (s *Plugin) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
// Find the name of a referenced ServiceAccountToken secret we can mount // Find the name of a referenced ServiceAccountToken secret we can mount
serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount) serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount)
if err != nil { if err != nil {
...@@ -502,7 +508,7 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service ...@@ -502,7 +508,7 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service
return nil return nil
} }
func (s *serviceAccount) createVolume(tokenVolumeName, secretName string) api.Volume { func (s *Plugin) createVolume(tokenVolumeName, secretName string) api.Volume {
if s.featureGate.Enabled(kubefeatures.BoundServiceAccountTokenVolume) { if s.featureGate.Enabled(kubefeatures.BoundServiceAccountTokenVolume) {
return api.Volume{ return api.Volume{
Name: tokenVolumeName, Name: tokenVolumeName,
......
...@@ -275,7 +275,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) { ...@@ -275,7 +275,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
} }
func TestAutomountsAPIToken(t *testing.T) { func TestAutomountsAPIToken(t *testing.T) {
testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*serviceAccount) *serviceAccount) { testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*Plugin) *Plugin) {
admit := applyFeatures(NewServiceAccount()) admit := applyFeatures(NewServiceAccount())
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
...@@ -385,7 +385,7 @@ func TestAutomountsAPIToken(t *testing.T) { ...@@ -385,7 +385,7 @@ func TestAutomountsAPIToken(t *testing.T) {
} }
func TestRespectsExistingMount(t *testing.T) { func TestRespectsExistingMount(t *testing.T) {
testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*serviceAccount) *serviceAccount) { testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*Plugin) *Plugin) {
ns := "myns" ns := "myns"
tokenName := "token-name" tokenName := "token-name"
serviceAccountName := DefaultServiceAccountName serviceAccountName := DefaultServiceAccountName
...@@ -914,7 +914,7 @@ func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName ...@@ -914,7 +914,7 @@ func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName
} }
func TestGetServiceAccountTokens(t *testing.T) { func TestGetServiceAccountTokens(t *testing.T) {
testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*serviceAccount) *serviceAccount) { testBoundServiceAccountTokenVolumePhases(t, func(t *testing.T, applyFeatures func(*Plugin) *Plugin) {
admit := applyFeatures(NewServiceAccount()) admit := applyFeatures(NewServiceAccount())
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
admit.secretLister = corev1listers.NewSecretLister(indexer) admit.secretLister = corev1listers.NewSecretLister(indexer)
...@@ -1070,16 +1070,16 @@ func testGenerateName(n string) string { ...@@ -1070,16 +1070,16 @@ func testGenerateName(n string) string {
var generatedVolumeName = testGenerateName(ServiceAccountVolumeName + "-") var generatedVolumeName = testGenerateName(ServiceAccountVolumeName + "-")
func testBoundServiceAccountTokenVolumePhases(t *testing.T, f func(*testing.T, func(*serviceAccount) *serviceAccount)) { func testBoundServiceAccountTokenVolumePhases(t *testing.T, f func(*testing.T, func(*Plugin) *Plugin)) {
t.Run("BoundServiceAccountTokenVolume disabled", func(t *testing.T) { t.Run("BoundServiceAccountTokenVolume disabled", func(t *testing.T) {
f(t, func(s *serviceAccount) *serviceAccount { f(t, func(s *Plugin) *Plugin {
s.featureGate = deprecationDisabledFeature s.featureGate = deprecationDisabledFeature
return s return s
}) })
}) })
t.Run("BoundServiceAccountTokenVolume enabled", func(t *testing.T) { t.Run("BoundServiceAccountTokenVolume enabled", func(t *testing.T) {
f(t, func(s *serviceAccount) *serviceAccount { f(t, func(s *Plugin) *Plugin {
s.featureGate = deprecationEnabledFeature s.featureGate = deprecationEnabledFeature
return s return s
}) })
......
...@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and ...@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// serviceaccount enforces all pods having an associated serviceaccount, // Package serviceaccount enforces all pods having an associated serviceaccount,
// and all containers mounting the API token for that serviceaccount at a known location // and all containers mounting the API token for that serviceaccount at a known location
package serviceaccount // import "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount" package serviceaccount // import "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment