diff --git a/hack/.golint_failures b/hack/.golint_failures index 3490d542e7..e3ce8377b9 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -320,20 +320,10 @@ pkg/volume/testing pkg/volume/util/fs pkg/volume/util/volumepathhandler pkg/volume/vsphere_volume -plugin/pkg/admission/antiaffinity plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1 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/v1beta1 -plugin/pkg/admission/security/podsecuritypolicy -plugin/pkg/admission/serviceaccount plugin/pkg/auth/authorizer/node plugin/pkg/auth/authorizer/rbac plugin/pkg/auth/authorizer/rbac/bootstrappolicy diff --git a/plugin/pkg/admission/antiaffinity/admission.go b/plugin/pkg/admission/antiaffinity/admission.go index 9e7e5592c0..94225fd652 100644 --- a/plugin/pkg/admission/antiaffinity/admission.go +++ b/plugin/pkg/admission/antiaffinity/admission.go @@ -26,6 +26,7 @@ import ( api "k8s.io/kubernetes/pkg/apis/core" ) +// PluginName is a string with the name of the plugin const PluginName = "LimitPodHardAntiAffinityTopology" // Register registers a plugin diff --git a/plugin/pkg/admission/antiaffinity/doc.go b/plugin/pkg/admission/antiaffinity/doc.go index 28db3a0434..5d79fb396b 100644 --- a/plugin/pkg/admission/antiaffinity/doc.go +++ b/plugin/pkg/admission/antiaffinity/doc.go @@ -14,15 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -// LimitPodHardAntiAffinityTopology admission controller rejects any pod -// that specifies "hard" (RequiredDuringScheduling) anti-affinity -// with a TopologyKey other than v1.LabelHostname. -// Because anti-affinity is symmetric, without this admission controller, -// a user could maliciously or accidentally specify that their pod (once it has scheduled) -// should block other pods from scheduling into the same zone or some other large topology, -// essentially DoSing the cluster. -// In the future we will address this problem more fully by using quota and priority, -// but for now this admission controller provides a simple protection, -// on the assumption that the only legitimate use of hard pod anti-affinity -// is to exclude other pods from the same node. +// Package antiaffinity provides the LimitPodHardAntiAffinityTopology +// admission controller. It rejects any pod that specifies "hard" +// (RequiredDuringScheduling) anti-affinity with a TopologyKey other +// than v1.LabelHostname. Because anti-affinity is symmetric, without +// this admission controller, a user could maliciously or accidentally +// specify that their pod (once it has scheduled) should block other +// pods from scheduling into the same zone or some other large +// topology, essentially DoSing the cluster. In the future we will +// address this problem more fully by using quota and priority, but +// for now this admission controller provides a simple protection, on +// 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" diff --git a/plugin/pkg/admission/eventratelimit/apis/eventratelimit/register.go b/plugin/pkg/admission/eventratelimit/apis/eventratelimit/register.go index c9f2ca8ec7..9c6ec8e1ec 100644 --- a/plugin/pkg/admission/eventratelimit/apis/eventratelimit/register.go +++ b/plugin/pkg/admission/eventratelimit/apis/eventratelimit/register.go @@ -24,7 +24,7 @@ import ( var ( // SchemeBuilder is the scheme builder with scheme init functions to run for this API package 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 ) diff --git a/plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1/register.go b/plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1/register.go index 74c039344d..8a2ed26ffc 100644 --- a/plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1/register.go +++ b/plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1/register.go @@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + + // SchemeBuilder is a pointer used to call AddToScheme SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + // AddToScheme is used to register the types to API encoding/decoding machinery + AddToScheme = localSchemeBuilder.AddToScheme ) func init() { diff --git a/plugin/pkg/admission/limitranger/admission.go b/plugin/pkg/admission/limitranger/admission.go index 3e2d761331..762cf28936 100644 --- a/plugin/pkg/admission/limitranger/admission.go +++ b/plugin/pkg/admission/limitranger/admission.go @@ -78,16 +78,19 @@ type liveLookupEntry struct { items []*corev1.LimitRange } +// SetExternalKubeInformerFactory registers an informer factory into the LimitRanger func (l *LimitRanger) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { limitRangeInformer := f.Core().V1().LimitRanges() l.SetReadyFunc(limitRangeInformer.Informer().HasSynced) l.lister = limitRangeInformer.Lister() } -func (a *LimitRanger) SetExternalKubeClientSet(client kubernetes.Interface) { - a.client = client +// SetExternalKubeClientSet registers the client into LimitRanger +func (l *LimitRanger) SetExternalKubeClientSet(client kubernetes.Interface) { + l.client = client } +// ValidateInitialization verifies the LimitRanger object has been properly initialized func (l *LimitRanger) ValidateInitialization() error { if l.lister == nil { return fmt.Errorf("missing limitRange lister") @@ -146,6 +149,8 @@ func (l *LimitRanger) runLimitFunc(a admission.Attributes, limitFn func(limitRan 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) { items, err := l.lister.LimitRanges(a.GetNamespace()).List(labels.Everything()) if err != nil { @@ -306,13 +311,13 @@ func minConstraint(limitType string, resourceName string, enforced resource.Quan observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced) 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 { - 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) { - 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 } @@ -324,10 +329,10 @@ func maxRequestConstraint(limitType string, resourceName string, enforced resour observedReqValue, _, enforcedValue := requestLimitEnforcedValues(req, resource.Quantity{}, enforced) 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 { - 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 } @@ -339,13 +344,13 @@ func maxConstraint(limitType string, resourceName string, enforced resource.Quan observedReqValue, observedLimValue, enforcedValue := requestLimitEnforcedValues(req, lim, enforced) 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 { - 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) { - 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 } @@ -357,10 +362,10 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced observedReqValue, observedLimValue, _ := requestLimitEnforcedValues(req, lim, enforced) 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)) { - 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) @@ -372,7 +377,7 @@ func limitRequestRatioConstraint(limitType string, resourceName string, enforced } 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 @@ -423,9 +428,10 @@ type DefaultLimitRangerActions struct{} // ensure DefaultLimitRangerActions implements the LimitRangerActions interface. var _ LimitRangerActions = &DefaultLimitRangerActions{} -// Limit enforces resource requirements of incoming resources against enumerated constraints -// on the LimitRange. It may modify the incoming object to apply default resource requirements -// if not specified, and enumerated on the LimitRange +// MutateLimit enforces resource requirements of incoming resources +// against enumerated constraints on the LimitRange. It may modify +// 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 { switch resourceName { case "pods": @@ -434,9 +440,9 @@ func (d *DefaultLimitRangerActions) MutateLimit(limitRange *corev1.LimitRange, r return nil } -// Limit enforces resource requirements of incoming resources against enumerated constraints -// on the LimitRange. It may modify the incoming object to apply default resource requirements -// if not specified, and enumerated on the LimitRange +// ValidateLimit verifies the resource requirements of incoming +// resources against enumerated constraints on the LimitRange are +// valid func (d *DefaultLimitRangerActions) ValidateLimit(limitRange *corev1.LimitRange, resourceName string, obj runtime.Object) error { switch resourceName { case "pods": diff --git a/plugin/pkg/admission/limitranger/admission_test.go b/plugin/pkg/admission/limitranger/admission_test.go index 0de495961d..afd648f003 100644 --- a/plugin/pkg/admission/limitranger/admission_test.go +++ b/plugin/pkg/admission/limitranger/admission_test.go @@ -656,42 +656,42 @@ func TestPodLimitFuncApplyDefault(t *testing.T) { for i := range testPod.Spec.Containers { container := testPod.Spec.Containers[i] limitMemory := container.Resources.Limits.Memory().String() - limitCpu := container.Resources.Limits.Cpu().String() + limitCPU := container.Resources.Limits.Cpu().String() requestMemory := container.Resources.Requests.Memory().String() - requestCpu := container.Resources.Requests.Cpu().String() + requestCPU := container.Resources.Requests.Cpu().String() if limitMemory != "10Mi" { t.Errorf("Unexpected limit memory value %s", limitMemory) } - if limitCpu != "75m" { - t.Errorf("Unexpected limit cpu value %s", limitCpu) + if limitCPU != "75m" { + t.Errorf("Unexpected limit cpu value %s", limitCPU) } if requestMemory != "5Mi" { t.Errorf("Unexpected request memory value %s", requestMemory) } - if requestCpu != "50m" { - t.Errorf("Unexpected request cpu value %s", requestCpu) + if requestCPU != "50m" { + t.Errorf("Unexpected request cpu value %s", requestCPU) } } for i := range testPod.Spec.InitContainers { container := testPod.Spec.InitContainers[i] limitMemory := container.Resources.Limits.Memory().String() - limitCpu := container.Resources.Limits.Cpu().String() + limitCPU := container.Resources.Limits.Cpu().String() requestMemory := container.Resources.Requests.Memory().String() - requestCpu := container.Resources.Requests.Cpu().String() + requestCPU := container.Resources.Requests.Cpu().String() if limitMemory != "10Mi" { t.Errorf("Unexpected limit memory value %s", limitMemory) } - if limitCpu != "75m" { - t.Errorf("Unexpected limit cpu value %s", limitCpu) + if limitCPU != "75m" { + t.Errorf("Unexpected limit cpu value %s", limitCPU) } if requestMemory != "5Mi" { t.Errorf("Unexpected request memory value %s", requestMemory) } - if requestCpu != "50m" { - t.Errorf("Unexpected request cpu value %s", requestCpu) + if requestCPU != "50m" { + t.Errorf("Unexpected request cpu value %s", requestCPU) } } } diff --git a/plugin/pkg/admission/limitranger/interfaces.go b/plugin/pkg/admission/limitranger/interfaces.go index 2ba469795a..35b6ce8c6f 100644 --- a/plugin/pkg/admission/limitranger/interfaces.go +++ b/plugin/pkg/admission/limitranger/interfaces.go @@ -22,6 +22,7 @@ import ( "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 { // MutateLimit is a pluggable function to set limits on the object. MutateLimit(limitRange *corev1.LimitRange, kind string, obj runtime.Object) error diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go index db0e00d714..554e643b2c 100644 --- a/plugin/pkg/admission/noderestriction/admission.go +++ b/plugin/pkg/admission/noderestriction/admission.go @@ -45,9 +45,8 @@ import ( kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" ) -const ( - PluginName = "NodeRestriction" -) +// PluginName is a string with the name of the plugin +const PluginName = "NodeRestriction" // Register registers a plugin func Register(plugins *admission.Plugins) { @@ -58,16 +57,16 @@ func Register(plugins *admission.Plugins) { // NewPlugin creates a new NodeRestriction admission plugin. // This plugin identifies requests from nodes -func NewPlugin(nodeIdentifier nodeidentifier.NodeIdentifier) *nodePlugin { - return &nodePlugin{ +func NewPlugin(nodeIdentifier nodeidentifier.NodeIdentifier) *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create, admission.Update, admission.Delete), nodeIdentifier: nodeIdentifier, features: utilfeature.DefaultFeatureGate, } } -// nodePlugin holds state for and implements the admission plugin. -type nodePlugin struct { +// Plugin holds state for and implements the admission plugin. +type Plugin struct { *admission.Handler nodeIdentifier nodeidentifier.NodeIdentifier podsGetter corev1lister.PodLister @@ -76,15 +75,17 @@ type nodePlugin struct { } var ( - _ = admission.Interface(&nodePlugin{}) - _ = apiserveradmission.WantsExternalKubeInformerFactory(&nodePlugin{}) + _ = admission.Interface(&Plugin{}) + _ = apiserveradmission.WantsExternalKubeInformerFactory(&Plugin{}) ) -func (p *nodePlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { +// SetExternalKubeInformerFactory registers an informer factory into Plugin +func (p *Plugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { p.podsGetter = f.Core().V1().Pods().Lister() } -func (p *nodePlugin) ValidateInitialization() error { +// ValidateInitialization validates the Plugin was initialized properly +func (p *Plugin) ValidateInitialization() error { if p.nodeIdentifier == nil { return fmt.Errorf("%s requires a node identifier", PluginName) } @@ -103,8 +104,9 @@ var ( csiNodeResource = storage.Resource("csinodes") ) -func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { - nodeName, isNode := c.nodeIdentifier.NodeIdentity(a.GetUserInfo()) +// Admit checks the admission policy and triggers corresponding actions +func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { + nodeName, isNode := p.nodeIdentifier.NodeIdentity(a.GetUserInfo()) // Our job is just to restrict nodes if !isNode { @@ -120,41 +122,41 @@ func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) case podResource: switch a.GetSubresource() { case "": - return c.admitPod(nodeName, a) + return p.admitPod(nodeName, a) case "status": - return c.admitPodStatus(nodeName, a) + return p.admitPodStatus(nodeName, a) case "eviction": - return c.admitPodEviction(nodeName, a) + return p.admitPodEviction(nodeName, a) default: return admission.NewForbidden(a, fmt.Errorf("unexpected pod subresource %q, only 'status' and 'eviction' are allowed", a.GetSubresource())) } case nodeResource: - return c.admitNode(nodeName, a) + return p.admitNode(nodeName, a) case pvcResource: switch a.GetSubresource() { case "status": - return c.admitPVCStatus(nodeName, a) + return p.admitPVCStatus(nodeName, a) default: return admission.NewForbidden(a, fmt.Errorf("may only update PVC status")) } case svcacctResource: - if c.features.Enabled(features.TokenRequest) { - return c.admitServiceAccount(nodeName, a) + if p.features.Enabled(features.TokenRequest) { + return p.admitServiceAccount(nodeName, a) } return nil case leaseResource: - if c.features.Enabled(features.NodeLease) { - return c.admitLease(nodeName, a) + if p.features.Enabled(features.NodeLease) { + return p.admitLease(nodeName, a) } return admission.NewForbidden(a, fmt.Errorf("disabled by feature gate %s", features.NodeLease)) case csiNodeResource: - if c.features.Enabled(features.KubeletPluginsWatcher) && c.features.Enabled(features.CSINodeInfo) { - return c.admitCSINode(nodeName, a) + if p.features.Enabled(features.KubeletPluginsWatcher) && p.features.Enabled(features.CSINodeInfo) { + return p.admitCSINode(nodeName, a) } return admission.NewForbidden(a, fmt.Errorf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo)) @@ -163,7 +165,9 @@ func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) } } -func (c *nodePlugin) admitPod(nodeName string, a admission.Attributes) error { +// admitPod allows creating or deleting a pod if it is assigned to the +// current node and fulfills related criteria. +func (p *Plugin) admitPod(nodeName string, a admission.Attributes) error { switch a.GetOperation() { case admission.Create: // require a pod object @@ -206,7 +210,7 @@ func (c *nodePlugin) admitPod(nodeName string, a admission.Attributes) error { case admission.Delete: // get the existing pod - existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(a.GetName()) + existingPod, err := p.podsGetter.Pods(a.GetNamespace()).Get(a.GetName()) if errors.IsNotFound(err) { return err } @@ -224,7 +228,9 @@ func (c *nodePlugin) admitPod(nodeName string, a admission.Attributes) error { } } -func (c *nodePlugin) admitPodStatus(nodeName string, a admission.Attributes) error { +// admitPodStatus allows to update the status of a pod if it is +// assigned to the current node. +func (p *Plugin) admitPodStatus(nodeName string, a admission.Attributes) error { switch a.GetOperation() { case admission.Update: // require an existing pod @@ -243,7 +249,8 @@ func (c *nodePlugin) admitPodStatus(nodeName string, a admission.Attributes) err } } -func (c *nodePlugin) admitPodEviction(nodeName string, a admission.Attributes) error { +// admitPodEviction allows to evict a pod if it is assigned to the current node. +func (p *Plugin) admitPodEviction(nodeName string, a admission.Attributes) error { switch a.GetOperation() { case admission.Create: // require eviction to an existing pod object @@ -260,7 +267,7 @@ func (c *nodePlugin) admitPodEviction(nodeName string, a admission.Attributes) e podName = eviction.Name } // get the existing pod - existingPod, err := c.podsGetter.Pods(a.GetNamespace()).Get(podName) + existingPod, err := p.podsGetter.Pods(a.GetNamespace()).Get(podName) if errors.IsNotFound(err) { return err } @@ -278,10 +285,10 @@ func (c *nodePlugin) admitPodEviction(nodeName string, a admission.Attributes) e } } -func (c *nodePlugin) admitPVCStatus(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitPVCStatus(nodeName string, a admission.Attributes) error { switch a.GetOperation() { case admission.Update: - if !c.features.Enabled(features.ExpandPersistentVolumes) { + if !p.features.Enabled(features.ExpandPersistentVolumes) { return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to update persistentvolumeclaim metadata", nodeName)) } @@ -328,7 +335,7 @@ func (c *nodePlugin) admitPVCStatus(nodeName string, a admission.Attributes) err } } -func (c *nodePlugin) admitNode(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitNode(nodeName string, a admission.Attributes) error { requestedName := a.GetName() if a.GetOperation() == admission.Create { node, ok := a.GetObject().(*api.Node) @@ -345,12 +352,12 @@ func (c *nodePlugin) admitNode(nodeName string, a admission.Attributes) error { // Don't allow a node to register with labels outside the allowed set. // This would allow a node to add or modify its labels in a way that would let it steer privileged workloads to itself. modifiedLabels := getModifiedLabels(node.Labels, nil) - if forbiddenLabels := c.getForbiddenCreateLabels(modifiedLabels); len(forbiddenLabels) > 0 { + if forbiddenLabels := p.getForbiddenCreateLabels(modifiedLabels); len(forbiddenLabels) > 0 { return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to set the following labels: %s", nodeName, strings.Join(forbiddenLabels.List(), ", "))) } // check and warn if nodes set labels on create that would have been forbidden on update // TODO(liggitt): in 1.17, expand getForbiddenCreateLabels to match getForbiddenUpdateLabels and drop this - if forbiddenUpdateLabels := c.getForbiddenUpdateLabels(modifiedLabels); len(forbiddenUpdateLabels) > 0 { + if forbiddenUpdateLabels := p.getForbiddenUpdateLabels(modifiedLabels); len(forbiddenUpdateLabels) > 0 { klog.Warningf("node %q added disallowed labels on node creation: %s", nodeName, strings.Join(forbiddenUpdateLabels.List(), ", ")) } @@ -389,7 +396,7 @@ func (c *nodePlugin) admitNode(nodeName string, a admission.Attributes) error { // Don't allow a node to update labels outside the allowed set. // This would allow a node to add or modify its labels in a way that would let it steer privileged workloads to itself. modifiedLabels := getModifiedLabels(node.Labels, oldNode.Labels) - if forbiddenUpdateLabels := c.getForbiddenUpdateLabels(modifiedLabels); len(forbiddenUpdateLabels) > 0 { + if forbiddenUpdateLabels := p.getForbiddenUpdateLabels(modifiedLabels); len(forbiddenUpdateLabels) > 0 { return admission.NewForbidden(a, fmt.Errorf("is not allowed to modify labels: %s", strings.Join(forbiddenUpdateLabels.List(), ", "))) } } @@ -433,7 +440,7 @@ func getLabelNamespace(key string) string { // getForbiddenCreateLabels returns the set of labels that may not be set by the node. // TODO(liggitt): in 1.17, expand to match getForbiddenUpdateLabels() -func (c *nodePlugin) getForbiddenCreateLabels(modifiedLabels sets.String) sets.String { +func (p *Plugin) getForbiddenCreateLabels(modifiedLabels sets.String) sets.String { if len(modifiedLabels) == 0 { return nil } @@ -450,7 +457,7 @@ func (c *nodePlugin) getForbiddenCreateLabels(modifiedLabels sets.String) sets.S } // getForbiddenLabels returns the set of labels that may not be set by the node on update. -func (c *nodePlugin) getForbiddenUpdateLabels(modifiedLabels sets.String) sets.String { +func (p *Plugin) getForbiddenUpdateLabels(modifiedLabels sets.String) sets.String { if len(modifiedLabels) == 0 { return nil } @@ -471,7 +478,7 @@ func (c *nodePlugin) getForbiddenUpdateLabels(modifiedLabels sets.String) sets.S return forbiddenLabels } -func (c *nodePlugin) admitServiceAccount(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitServiceAccount(nodeName string, a admission.Attributes) error { if a.GetOperation() != admission.Create { return nil } @@ -495,7 +502,7 @@ func (c *nodePlugin) admitServiceAccount(nodeName string, a admission.Attributes if ref.UID == "" { return admission.NewForbidden(a, fmt.Errorf("node requested token with a pod binding without a uid")) } - pod, err := c.podsGetter.Pods(a.GetNamespace()).Get(ref.Name) + pod, err := p.podsGetter.Pods(a.GetNamespace()).Get(ref.Name) if errors.IsNotFound(err) { return err } @@ -512,7 +519,7 @@ func (c *nodePlugin) admitServiceAccount(nodeName string, a admission.Attributes return nil } -func (r *nodePlugin) admitLease(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitLease(nodeName string, a admission.Attributes) error { // the request must be against the system namespace reserved for node leases if a.GetNamespace() != api.NamespaceNodeLease { return admission.NewForbidden(a, fmt.Errorf("can only access leases in the %q system namespace", api.NamespaceNodeLease)) @@ -537,7 +544,7 @@ func (r *nodePlugin) admitLease(nodeName string, a admission.Attributes) error { return nil } -func (c *nodePlugin) admitCSINode(nodeName string, a admission.Attributes) error { +func (p *Plugin) admitCSINode(nodeName string, a admission.Attributes) error { // the request must come from a node with the same name as the CSINode object if a.GetOperation() == admission.Create { // a.GetName() won't return the name on create, so we drill down to the proposed object diff --git a/plugin/pkg/admission/podnodeselector/admission.go b/plugin/pkg/admission/podnodeselector/admission.go index 103397f757..e5ad477bfb 100644 --- a/plugin/pkg/admission/podnodeselector/admission.go +++ b/plugin/pkg/admission/podnodeselector/admission.go @@ -36,10 +36,12 @@ import ( api "k8s.io/kubernetes/pkg/apis/core" ) -// The annotation key scheduler.alpha.kubernetes.io/node-selector is for assigning -// node selectors labels to namespaces +// NamespaceNodeSelectors is for assigning node selectors labels to +// namespaces. Default value is the annotation key +// 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" // Register registers a plugin @@ -52,8 +54,8 @@ func Register(plugins *admission.Plugins) { }) } -// podNodeSelector is an implementation of admission.Interface. -type podNodeSelector struct { +// Plugin is an implementation of admission.Interface. +type Plugin struct { *admission.Handler client kubernetes.Interface namespaceLister corev1listers.NamespaceLister @@ -61,8 +63,8 @@ type podNodeSelector struct { clusterNodeSelectors map[string]string } -var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podNodeSelector{}) -var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podNodeSelector{}) +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{}) type pluginConfig struct { PodNodeSelectorPluginConfig map[string]string @@ -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. -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) { return nil } @@ -121,7 +123,7 @@ func (p *podNodeSelector) Admit(a admission.Attributes, o admission.ObjectInterf } // 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) { return nil } @@ -152,7 +154,7 @@ func (p *podNodeSelector) Validate(a admission.Attributes, o admission.ObjectInt 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) if errors.IsNotFound(err) { namespace, err = p.defaultGetNamespace(namespaceName) @@ -188,24 +190,28 @@ func shouldIgnore(a admission.Attributes) bool { return false } -func NewPodNodeSelector(clusterNodeSelectors map[string]string) *podNodeSelector { - return &podNodeSelector{ +// NewPodNodeSelector initializes a podNodeSelector +func NewPodNodeSelector(clusterNodeSelectors map[string]string) *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create), clusterNodeSelectors: clusterNodeSelectors, } } -func (a *podNodeSelector) SetExternalKubeClientSet(client kubernetes.Interface) { - a.client = client +// SetExternalKubeClientSet sets the plugin's 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() p.namespaceLister = namespaceInformer.Lister() 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 { return fmt.Errorf("missing namespaceLister") } @@ -215,7 +221,7 @@ func (p *podNodeSelector) ValidateInitialization() error { 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{}) if err != nil { return nil, fmt.Errorf("namespace %s does not exist", name) @@ -223,7 +229,7 @@ func (p *podNodeSelector) defaultGetNamespace(name string) (*corev1.Namespace, e 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{} labelsMap := labels.Set{} var err error diff --git a/plugin/pkg/admission/podnodeselector/admission_test.go b/plugin/pkg/admission/podnodeselector/admission_test.go index b7596ed764..0444b07010 100644 --- a/plugin/pkg/admission/podnodeselector/admission_test.go +++ b/plugin/pkg/admission/podnodeselector/admission_test.go @@ -194,7 +194,7 @@ func TestHandles(t *testing.T) { } // 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) handler := NewPodNodeSelector(nil) pluginInitializer := genericadmissioninitializer.New(c, f, nil) diff --git a/plugin/pkg/admission/podpreset/admission.go b/plugin/pkg/admission/podpreset/admission.go index 58b9692562..3a99155414 100644 --- a/plugin/pkg/admission/podpreset/admission.go +++ b/plugin/pkg/admission/podpreset/admission.go @@ -40,7 +40,8 @@ import ( const ( annotationPrefix = "podpreset.admission.kubernetes.io" - PluginName = "PodPreset" + // PluginName is a string with the name of the plugin + PluginName = "PodPreset" ) // Register registers a plugin @@ -50,47 +51,50 @@ func Register(plugins *admission.Plugins) { }) } -// podPresetPlugin is an implementation of admission.Interface. -type podPresetPlugin struct { +// Plugin is an implementation of admission.Interface. +type Plugin struct { *admission.Handler client kubernetes.Interface lister settingsv1alpha1listers.PodPresetLister } -var _ admission.MutationInterface = &podPresetPlugin{} -var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podPresetPlugin{}) -var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podPresetPlugin{}) +var _ admission.MutationInterface = &Plugin{} +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{}) // NewPlugin creates a new pod preset admission plugin. -func NewPlugin() *podPresetPlugin { - return &podPresetPlugin{ +func NewPlugin() *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create, admission.Update), } } -func (plugin *podPresetPlugin) ValidateInitialization() error { - if plugin.client == nil { +// ValidateInitialization validates the Plugin was initialized properly +func (p *Plugin) ValidateInitialization() error { + if p.client == nil { 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 nil } -func (a *podPresetPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { - a.client = client +// SetExternalKubeClientSet registers the client into Plugin +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() - a.lister = podPresetInformer.Lister() - a.SetReadyFunc(podPresetInformer.Informer().HasSynced) + p.lister = podPresetInformer.Lister() + p.SetReadyFunc(podPresetInformer.Informer().HasSynced) } // 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 operations other than 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 } } - list, err := c.lister.PodPresets(a.GetNamespace()).List(labels.Everything()) + list, err := p.lister.PodPresets(a.GetNamespace()).List(labels.Everything()) if err != nil { return fmt.Errorf("listing pod presets failed: %v", err) } diff --git a/plugin/pkg/admission/podpreset/admission_test.go b/plugin/pkg/admission/podpreset/admission_test.go index ed894ae6ae..381a721695 100644 --- a/plugin/pkg/admission/podpreset/admission_test.go +++ b/plugin/pkg/admission/podpreset/admission_test.go @@ -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 client := fake.NewSimpleClientset(objects...) - return &podPresetPlugin{ + return &Plugin{ client: client, Handler: kadmission.NewHandler(kadmission.Create), lister: lister, diff --git a/plugin/pkg/admission/podtolerationrestriction/BUILD b/plugin/pkg/admission/podtolerationrestriction/BUILD index b0ff10f44c..3e8d84eb05 100644 --- a/plugin/pkg/admission/podtolerationrestriction/BUILD +++ b/plugin/pkg/admission/podtolerationrestriction/BUILD @@ -35,6 +35,7 @@ go_library( srcs = [ "admission.go", "config.go", + "doc.go", ], importpath = "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction", deps = [ diff --git a/plugin/pkg/admission/podtolerationrestriction/admission.go b/plugin/pkg/admission/podtolerationrestriction/admission.go index 8c16840d4a..27b183d8e4 100644 --- a/plugin/pkg/admission/podtolerationrestriction/admission.go +++ b/plugin/pkg/admission/podtolerationrestriction/admission.go @@ -39,6 +39,7 @@ import ( pluginapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction" ) +// PluginName is a string with the name of the plugin const PluginName = "PodTolerationRestriction" // Register registers a plugin @@ -58,29 +59,21 @@ const ( NSWLTolerations string = "scheduler.alpha.kubernetes.io/tolerationsWhitelist" ) -var _ admission.MutationInterface = &podTolerationsPlugin{} -var _ admission.ValidationInterface = &podTolerationsPlugin{} -var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&podTolerationsPlugin{}) -var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&podTolerationsPlugin{}) +var _ admission.MutationInterface = &Plugin{} +var _ admission.ValidationInterface = &Plugin{} +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{}) -type podTolerationsPlugin struct { +// Plugin contains the client used by the admission controller +type Plugin struct { *admission.Handler client kubernetes.Interface namespaceLister corev1listers.NamespaceLister pluginConfig *pluginapi.Configuration } -// This plugin 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. -func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { +// Admit checks the admission policy and triggers corresponding actions +func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { if shouldIgnore(a) { return nil } @@ -136,7 +129,9 @@ func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectI pod.Spec.Tolerations = tolerations.MergeTolerations(finalTolerations, []api.Toleration{}) 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) { return nil } @@ -190,25 +185,29 @@ func shouldIgnore(a admission.Attributes) bool { return false } -func NewPodTolerationsPlugin(pluginConfig *pluginapi.Configuration) *podTolerationsPlugin { - return &podTolerationsPlugin{ +// NewPodTolerationsPlugin initializes a Plugin +func NewPodTolerationsPlugin(pluginConfig *pluginapi.Configuration) *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create, admission.Update), pluginConfig: pluginConfig, } } -func (a *podTolerationsPlugin) SetExternalKubeClientSet(client kubernetes.Interface) { - a.client = client +// SetExternalKubeClientSet sets th 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() p.namespaceLister = namespaceInformer.Lister() 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 { return fmt.Errorf("missing namespaceLister") } @@ -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. -func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, error) { +func (p *Plugin) getNamespace(nsName string) (*corev1.Namespace, error) { namespace, err := p.namespaceLister.Get(nsName) 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 @@ -237,7 +236,7 @@ func (p *podTolerationsPlugin) getNamespace(nsName string) (*corev1.Namespace, e 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) if err != nil { return nil, err @@ -245,7 +244,7 @@ func (p *podTolerationsPlugin) getNamespaceDefaultTolerations(nsName string) ([] 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) if err != nil { return nil, err diff --git a/plugin/pkg/admission/podtolerationrestriction/admission_test.go b/plugin/pkg/admission/podtolerationrestriction/admission_test.go index 484e34bff3..e958d50f2b 100644 --- a/plugin/pkg/admission/podtolerationrestriction/admission_test.go +++ b/plugin/pkg/admission/podtolerationrestriction/admission_test.go @@ -350,7 +350,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { } // 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) pluginConfig, err := loadConfiguration(nil) // must not fail diff --git a/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/register.go b/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/register.go index db676791fd..0360bf213b 100644 --- a/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/register.go +++ b/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/register.go @@ -30,7 +30,7 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime. var ( // SchemeBuilder is the scheme builder with scheme init functions to run for this API package 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 ) diff --git a/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1/register.go b/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1/register.go index 3270ec8003..1744f0726b 100644 --- a/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1/register.go +++ b/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1/register.go @@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + + // SchemeBuilder is a pointer used to call AddToScheme SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + // AddToScheme is used to register the types to API encoding/decoding machinery + AddToScheme = localSchemeBuilder.AddToScheme ) func init() { diff --git a/plugin/pkg/admission/podtolerationrestriction/doc.go b/plugin/pkg/admission/podtolerationrestriction/doc.go new file mode 100644 index 0000000000..03976264c9 --- /dev/null +++ b/plugin/pkg/admission/podtolerationrestriction/doc.go @@ -0,0 +1,30 @@ +/* +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" diff --git a/plugin/pkg/admission/resourcequota/admission.go b/plugin/pkg/admission/resourcequota/admission.go index 0fad34051f..0865ef3345 100644 --- a/plugin/pkg/admission/resourcequota/admission.go +++ b/plugin/pkg/admission/resourcequota/admission.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation" ) +// PluginName is a string with the name of the plugin const PluginName = "ResourceQuota" // Register registers a plugin @@ -93,14 +94,17 @@ func NewResourceQuota(config *resourcequotaapi.Configuration, numEvaluators int, }, nil } +// SetExternalKubeClientSet registers the client into QuotaAdmission func (a *QuotaAdmission) SetExternalKubeClientSet(client kubernetes.Interface) { a.quotaAccessor.client = client } +// SetExternalKubeInformerFactory registers an informer factory into QuotaAdmission func (a *QuotaAdmission) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) { a.quotaAccessor.lister = f.Core().V1().ResourceQuotas().Lister() } +// SetQuotaConfiguration assigns and initializes configuration and evaluator for QuotaAdmission func (a *QuotaAdmission) SetQuotaConfiguration(c quota.Configuration) { a.quotaConfiguration = c a.evaluator = NewQuotaEvaluator(a.quotaAccessor, a.quotaConfiguration.IgnoredResources(), generic.NewRegistry(a.quotaConfiguration.Evaluators()), nil, a.config, a.numEvaluators, a.stopCh) diff --git a/plugin/pkg/admission/resourcequota/apis/resourcequota/register.go b/plugin/pkg/admission/resourcequota/apis/resourcequota/register.go index 57abb758db..e36b7143fa 100644 --- a/plugin/pkg/admission/resourcequota/apis/resourcequota/register.go +++ b/plugin/pkg/admission/resourcequota/apis/resourcequota/register.go @@ -22,8 +22,10 @@ import ( ) var ( + // SchemeBuilder is a pointer used to call AddToScheme 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 diff --git a/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1/register.go b/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1/register.go index 5b4117695a..df604f689f 100644 --- a/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1/register.go +++ b/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1/register.go @@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + + // SchemeBuilder is a pointer used to call AddToScheme SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + // AddToScheme is used to register the types to API encoding/decoding machinery + AddToScheme = localSchemeBuilder.AddToScheme ) func init() { diff --git a/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go b/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go index 20e5e45283..0bdbc14f05 100644 --- a/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go +++ b/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go @@ -30,9 +30,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1 var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + + // SchemeBuilder is a pointer used to call AddToScheme SchemeBuilder runtime.SchemeBuilder localSchemeBuilder = &SchemeBuilder - AddToScheme = localSchemeBuilder.AddToScheme + // AddToScheme is used to register the types to API encoding/decoding machinery + AddToScheme = localSchemeBuilder.AddToScheme ) func init() { diff --git a/plugin/pkg/admission/resourcequota/doc.go b/plugin/pkg/admission/resourcequota/doc.go index 3dd1422872..42bee9fbab 100644 --- a/plugin/pkg/admission/resourcequota/doc.go +++ b/plugin/pkg/admission/resourcequota/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and 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 package resourcequota // import "k8s.io/kubernetes/plugin/pkg/admission/resourcequota" diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission.go b/plugin/pkg/admission/security/podsecuritypolicy/admission.go index 6a0752272d..aee1484b1f 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission.go @@ -43,9 +43,8 @@ import ( "k8s.io/kubernetes/pkg/serviceaccount" ) -const ( - PluginName = "PodSecurityPolicy" -) +// PluginName is a string with the name of the plugin +const PluginName = "PodSecurityPolicy" // Register registers a plugin func Register(plugins *admission.Plugins) { @@ -55,8 +54,8 @@ func Register(plugins *admission.Plugins) { }) } -// PodSecurityPolicyPlugin holds state for and implements the admission plugin. -type PodSecurityPolicyPlugin struct { +// Plugin holds state for and implements the admission plugin. +type Plugin struct { *admission.Handler strategyFactory psp.StrategyFactory failOnNoPolicies bool @@ -65,40 +64,41 @@ type PodSecurityPolicyPlugin struct { } // SetAuthorizer sets the authorizer. -func (plugin *PodSecurityPolicyPlugin) SetAuthorizer(authz authorizer.Authorizer) { - plugin.authz = authz +func (p *Plugin) SetAuthorizer(authz authorizer.Authorizer) { + p.authz = authz } // ValidateInitialization ensures an authorizer is set. -func (plugin *PodSecurityPolicyPlugin) ValidateInitialization() error { - if plugin.authz == nil { +func (p *Plugin) ValidateInitialization() error { + if p.authz == nil { 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 nil } -var _ admission.MutationInterface = &PodSecurityPolicyPlugin{} -var _ admission.ValidationInterface = &PodSecurityPolicyPlugin{} -var _ genericadmissioninit.WantsAuthorizer = &PodSecurityPolicyPlugin{} -var _ genericadmissioninit.WantsExternalKubeInformerFactory = &PodSecurityPolicyPlugin{} +var _ admission.MutationInterface = &Plugin{} +var _ admission.ValidationInterface = &Plugin{} +var _ genericadmissioninit.WantsAuthorizer = &Plugin{} +var _ genericadmissioninit.WantsExternalKubeInformerFactory = &Plugin{} var auditKeyPrefix = strings.ToLower(PluginName) + "." + policy.GroupName + ".k8s.io" // newPlugin creates a new PSP admission plugin. -func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *PodSecurityPolicyPlugin { - return &PodSecurityPolicyPlugin{ +func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create, admission.Update), strategyFactory: strategyFactory, 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() - a.lister = podSecurityPolicyInformer.Lister() - a.SetReadyFunc(podSecurityPolicyInformer.Informer().HasSynced) + p.lister = podSecurityPolicyInformer.Lister() + p.SetReadyFunc(podSecurityPolicyInformer.Informer().HasSynced) } // 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 // 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 // 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 { return err } else if ignore { @@ -125,7 +125,7 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.Obje pod := a.GetObject().(*api.Pod) // 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 { return admission.NewForbidden(a, err) } @@ -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)) } -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 { return err } else if ignore { @@ -159,7 +160,7 @@ func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes, o admission.O pod := a.GetObject().(*api.Pod) // 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 { return admission.NewForbidden(a, err) } @@ -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 // 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. -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 klog.V(4).Infof("getting pod security policies for pod %s (generate: %s)", pod.Name, pod.GenerateName) var saInfo user.Info @@ -213,14 +214,14 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, 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 { return nil, "", nil, err } // 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. - if len(policies) == 0 && !c.failOnNoPolicies { + if len(policies) == 0 && !p.failOnNoPolicies { return pod, "", nil, nil } @@ -239,7 +240,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, 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 { klog.V(4).Infof("provider creation error: %v", err) } @@ -269,7 +270,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, continue } - if !isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), c.authz) { + if !isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), p.authz) { continue } @@ -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. aggregate := field.ErrorList{} 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...) } } @@ -317,7 +318,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList } // 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 ( // collected providers providers []psp.Provider @@ -326,7 +327,7 @@ func (c *PodSecurityPolicyPlugin) createProvidersFromPolicies(psps []*policyv1be ) for _, constraint := range psps { - provider, err := psp.NewSimpleProvider(constraint, namespace, c.strategyFactory) + provider, err := psp.NewSimpleProvider(constraint, namespace, p.strategyFactory) if err != nil { errs = append(errs, fmt.Errorf("error creating provider for PSP %s: %v", constraint.Name, err)) continue diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go index ceeb0981d1..91081e69c6 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go @@ -53,7 +53,7 @@ import ( const defaultContainerName = "test-c" // 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()) store := informerFactory.Policy().V1beta1().PodSecurityPolicies().Informer().GetStore() for _, psp := range psps { @@ -63,7 +63,7 @@ func NewTestAdmission(psps []*policy.PodSecurityPolicy, authz authorizer.Authori if authz == nil { authz = &TestAuthorizer{} } - return &PodSecurityPolicyPlugin{ + return &Plugin{ Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update), strategyFactory: kpsp.NewSimpleStrategyFactory(), authz: authz, @@ -1963,7 +1963,7 @@ func TestCreateProvidersFromConstraints(t *testing.T) { } for k, v := range testCases { - admit := &PodSecurityPolicyPlugin{ + admit := &Plugin{ Handler: kadmission.NewHandler(kadmission.Create, kadmission.Update), strategyFactory: kpsp.NewSimpleStrategyFactory(), } diff --git a/plugin/pkg/admission/serviceaccount/admission.go b/plugin/pkg/admission/serviceaccount/admission.go index 048a2db5fd..974940f101 100644 --- a/plugin/pkg/admission/serviceaccount/admission.go +++ b/plugin/pkg/admission/serviceaccount/admission.go @@ -52,6 +52,7 @@ const ( // The value must be true to have this annotation take effect 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" // DefaultAPITokenMountPath is the path that ServiceAccountToken secrets are automounted to. @@ -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 // LimitSecretReferences rejects pods that reference secrets their service accounts do not reference @@ -92,10 +94,10 @@ type serviceAccount struct { featureGate featuregate.FeatureGate } -var _ admission.MutationInterface = &serviceAccount{} -var _ admission.ValidationInterface = &serviceAccount{} -var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&serviceAccount{}) -var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAccount{}) +var _ admission.MutationInterface = &Plugin{} +var _ admission.ValidationInterface = &Plugin{} +var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{}) +var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{}) // 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" @@ -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 // 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 -func NewServiceAccount() *serviceAccount { - return &serviceAccount{ +func NewServiceAccount() *Plugin { + return &Plugin{ Handler: admission.NewHandler(admission.Create), // TODO: enable this once we've swept secret usage to account for adding secret references to service accounts LimitSecretReferences: false, @@ -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 } -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() s.serviceAccountLister = serviceAccountInformer.Lister() @@ -136,7 +140,7 @@ func (s *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInform } // ValidateInitialization ensures an authorizer is set. -func (s *serviceAccount) ValidateInitialization() error { +func (s *Plugin) ValidateInitialization() error { if s.client == nil { return fmt.Errorf("missing client") } @@ -149,7 +153,8 @@ func (s *serviceAccount) ValidateInitialization() error { 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) { return nil } @@ -190,7 +195,8 @@ func (s *serviceAccount) Admit(a admission.Attributes, o admission.ObjectInterfa 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) { return nil } @@ -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 // 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 { return true } @@ -285,7 +291,7 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceA } // 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) if err == nil { return serviceAccount, nil @@ -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 -func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) { +func (s *Plugin) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) { if len(serviceAccount.Secrets) == 0 { return "", nil } @@ -343,7 +349,7 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1 } // 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()) if err != nil { return nil, err @@ -363,7 +369,7 @@ func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceA 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 mountableSecrets := sets.NewString() for _, s := range serviceAccount.Secrets { @@ -413,7 +419,7 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAcc 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 serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount) if err != nil { @@ -502,7 +508,7 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.Service 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) { return api.Volume{ Name: tokenVolumeName, diff --git a/plugin/pkg/admission/serviceaccount/admission_test.go b/plugin/pkg/admission/serviceaccount/admission_test.go index 5806035b0b..4a8e2ca89b 100644 --- a/plugin/pkg/admission/serviceaccount/admission_test.go +++ b/plugin/pkg/admission/serviceaccount/admission_test.go @@ -275,7 +275,7 @@ func TestDeniesInvalidServiceAccount(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()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) @@ -385,7 +385,7 @@ func TestAutomountsAPIToken(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" tokenName := "token-name" serviceAccountName := DefaultServiceAccountName @@ -914,7 +914,7 @@ func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName } 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()) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) admit.secretLister = corev1listers.NewSecretLister(indexer) @@ -1070,16 +1070,16 @@ func testGenerateName(n string) string { 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) { - f(t, func(s *serviceAccount) *serviceAccount { + f(t, func(s *Plugin) *Plugin { s.featureGate = deprecationDisabledFeature return s }) }) t.Run("BoundServiceAccountTokenVolume enabled", func(t *testing.T) { - f(t, func(s *serviceAccount) *serviceAccount { + f(t, func(s *Plugin) *Plugin { s.featureGate = deprecationEnabledFeature return s }) diff --git a/plugin/pkg/admission/serviceaccount/doc.go b/plugin/pkg/admission/serviceaccount/doc.go index 4bd511699a..a4810bb871 100644 --- a/plugin/pkg/admission/serviceaccount/doc.go +++ b/plugin/pkg/admission/serviceaccount/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and 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 package serviceaccount // import "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount"