} type internalConfig struct { limitCPUToMemoryRatio *inf.Dec cpuRequestToLimitRatio *inf.Dec memoryRequestToLimitRatio *inf.Dec } type clusterResourceOverridePlugin struct { *admission.Handler config *internalConfig ProjectCache *cache.ProjectCache LimitRanger admission.Interface } var _ = oadmission.WantsProjectCache(&clusterResourceOverridePlugin{}) var _ = oadmission.Validator(&clusterResourceOverridePlugin{}) // newClusterResourceOverride returns an admission controller for containers that // configurably overrides container resource request/limits func newClusterResourceOverride(client clientset.Interface, config io.Reader) (admission.Interface, error) { parsed, err := ReadConfig(config) if err != nil { glog.V(5).Infof("%s admission controller loaded with error: (%T) %[2]v", api.PluginName, err) return nil, err } if errs := validation.Validate(parsed); len(errs) > 0 { return nil, errs.ToAggregate() } glog.V(5).Infof("%s admission controller loaded with config: %v", api.PluginName, parsed) var internal *internalConfig if parsed != nil {
return nil, errs.ToAggregate() } return config, nil } type projectRequestLimit struct { *admission.Handler client client.Interface config *ProjectRequestLimitConfig cache *projectcache.ProjectCache } // ensure that the required Openshift admission interfaces are implemented var _ = oadmission.WantsProjectCache(&projectRequestLimit{}) var _ = oadmission.WantsOpenshiftClient(&projectRequestLimit{}) var _ = oadmission.Validator(&projectRequestLimit{}) // Admit ensures that only a configured number of projects can be requested by a particular user. func (o *projectRequestLimit) Admit(a admission.Attributes) (err error) { if a.GetResource() != projectapi.Resource("projectrequests") { return nil } if _, isProjectRequest := a.GetObject().(*projectapi.ProjectRequest); !isProjectRequest { return nil } userName := a.GetUserInfo().GetName() projectCount, err := o.projectCountByRequester(userName) if err != nil { return err } maxProjects, hasLimit, err := o.maxProjectsByRequester(userName)
admission.RegisterPlugin("OriginNamespaceLifecycle", func(client client.Interface, config io.Reader) (admission.Interface, error) { return NewLifecycle(client, recommendedCreatableResources) }) } type lifecycle struct { client client.Interface cache *cache.ProjectCache // creatableResources is a set of resources that can be created even if the namespace is terminating creatableResources sets.String } var recommendedCreatableResources = sets.NewString("resourceaccessreviews", "localresourceaccessreviews") var _ = oadmission.WantsProjectCache(&lifecycle{}) var _ = oadmission.Validator(&lifecycle{}) // Admit enforces that a namespace must exist in order to associate content with it. // Admit enforces that a namespace that is terminating cannot accept new content being associated with it. func (e *lifecycle) Admit(a admission.Attributes) (err error) { if len(a.GetNamespace()) == 0 { return nil } // always allow a SAR request through, the SAR will return information about // the ability to take action on the object, no need to verify it here. if isSubjectAccessReview(a) { return nil } mapping, err := latest.RESTMapper.RESTMapping(a.GetKind()) if err != nil { glog.V(4).Infof("Ignoring life-cycle enforcement for resource %v; no associated default version and kind could be found.", a.GetResource())
*admission.Handler config *api.ImagePolicyConfig client client.Interface accepter rules.Accepter integratedRegistryMatcher integratedRegistryMatcher resolveGroupResources []unversioned.GroupResource projectCache *cache.ProjectCache resolver imageResolver } var _ = oadmission.WantsOpenshiftClient(&imagePolicyPlugin{}) var _ = oadmission.Validator(&imagePolicyPlugin{}) var _ = oadmission.WantsDefaultRegistryFunc(&imagePolicyPlugin{}) type integratedRegistryMatcher struct { rules.RegistryMatcher } // imageResolver abstracts identifying an image for a particular reference. type imageResolver interface { ResolveObjectReference(ref *kapi.ObjectReference, defaultNamespace string) (*rules.ImagePolicyAttributes, error) } // imagePolicyPlugin returns an admission controller for pods that controls what images are allowed to run on the // cluster. func newImagePolicyPlugin(client clientset.Interface, parsed *api.ImagePolicyConfig) (*imagePolicyPlugin, error) { m := integratedRegistryMatcher{
var resourcesToIgnore = []unversioned.GroupKind{ extensions.Kind("DaemonSet"), } func shouldCheckResource(resource unversioned.GroupResource, kind unversioned.GroupKind) (bool, error) { expectedKind, shouldCheck := resourcesToCheck[resource] if !shouldCheck { return false, nil } if expectedKind != kind { return false, fmt.Errorf("Unexpected resource kind %v for resource %v", &kind, &resource) } return true, nil } var _ = oadmission.Validator(&podNodeConstraints{}) var _ = oadmission.WantsAuthorizer(&podNodeConstraints{}) func readConfig(reader io.Reader) (*api.PodNodeConstraintsConfig, error) { if reader == nil || reflect.ValueOf(reader).IsNil() { return nil, nil } obj, err := configlatest.ReadYAML(reader) if err != nil { return nil, err } if obj == nil { return nil, nil } config, ok := obj.(*api.PodNodeConstraintsConfig) if !ok {
oadmission "github.com/openshift/origin/pkg/cmd/server/admission" ) func init() { admission.RegisterPlugin("BuildByStrategy", func(c clientset.Interface, config io.Reader) (admission.Interface, error) { return NewBuildByStrategy(), nil }) } type buildByStrategy struct { *admission.Handler client client.Interface } var _ = oadmission.WantsOpenshiftClient(&buildByStrategy{}) var _ = oadmission.Validator(&buildByStrategy{}) // NewBuildByStrategy returns an admission control for builds that checks // on policy based on the build strategy type func NewBuildByStrategy() admission.Interface { return &buildByStrategy{ Handler: admission.NewHandler(admission.Create, admission.Update), } } var ( buildsResource = buildapi.Resource("builds") buildConfigsResource = buildapi.Resource("buildconfigs") ) func (a *buildByStrategy) Admit(attr admission.Attributes) error {
func init() { admission.RegisterPlugin("OriginPodNodeEnvironment", func(client clientset.Interface, config io.Reader) (admission.Interface, error) { return NewPodNodeEnvironment(client) }) } // podNodeEnvironment is an implementation of admission.Interface. type podNodeEnvironment struct { *admission.Handler client clientset.Interface cache *cache.ProjectCache } var _ = oadmission.WantsProjectCache(&podNodeEnvironment{}) var _ = oadmission.Validator(&podNodeEnvironment{}) // Admit enforces that pod and its project node label selectors matches at least a node in the cluster. func (p *podNodeEnvironment) Admit(a admission.Attributes) (err error) { resource := a.GetResource() if resource != kapi.Resource("pods") { return nil } if a.GetSubresource() != "" { // only run the checks below on pods proper and not subresources return nil } obj := a.GetObject() pod, ok := obj.(*kapi.Pod) if !ok {
func(kClient clientset.Interface, config io.Reader) (admission.Interface, error) { return NewOriginResourceQuota(kClient), nil }) } // originQuotaAdmission implements an admission controller that can enforce quota constraints on images and image // streams type originQuotaAdmission struct { *admission.Handler kQuotaAdmission admission.Interface // must be able to read/write ResourceQuota kClient clientset.Interface } var _ = oadmission.WantsOriginQuotaRegistry(&originQuotaAdmission{}) var _ = oadmission.Validator(&originQuotaAdmission{}) // NewOriginResourceQuota creates a new OriginResourceQuota admission plugin that takes care of admission of // origin resources abusing resource quota. func NewOriginResourceQuota(kClient clientset.Interface) admission.Interface { // defer an initialization of upstream controller until os client is set return &originQuotaAdmission{ Handler: admission.NewHandler(admission.Create, admission.Update), kClient: kClient, } } func (a *originQuotaAdmission) Admit(as admission.Attributes) error { return a.kQuotaAdmission.Admit(as) }
func NewRunOnceDuration(config *api.RunOnceDurationConfig) admission.Interface { return &runOnceDuration{ Handler: admission.NewHandler(admission.Create, admission.Update), config: config, } } type runOnceDuration struct { *admission.Handler config *api.RunOnceDurationConfig cache *projectcache.ProjectCache } var _ = oadmission.WantsProjectCache(&runOnceDuration{}) var _ = oadmission.Validator(&runOnceDuration{}) func (a *runOnceDuration) Admit(attributes admission.Attributes) error { switch { case a.config == nil, !a.config.Enabled, attributes.GetResource() != kapi.Resource("pods"), len(attributes.GetSubresource()) > 0: return nil } pod, ok := attributes.GetObject().(*kapi.Pod) if !ok { return admission.NewForbidden(attributes, fmt.Errorf("unexpected object: %#v", attributes.GetObject())) } // Only update pods with a restart policy of Never or OnFailure
} // restrictUsersAdmission implements admission.Interface and enforces // restrictions on adding rolebindings in a project to permit only designated // subjects. type restrictUsersAdmission struct { *admission.Handler oclient oclient.Interface kclient kclientset.Interface groupCache *usercache.GroupCache } var _ = oadmission.WantsOpenshiftClient(&restrictUsersAdmission{}) var _ = oadmission.WantsGroupCache(&restrictUsersAdmission{}) var _ = oadmission.Validator(&restrictUsersAdmission{}) // NewRestrictUsersAdmission configures an admission plugin that enforces // restrictions on adding role bindings in a project. func NewRestrictUsersAdmission(kclient kclientset.Interface) (admission.Interface, error) { return &restrictUsersAdmission{ Handler: admission.NewHandler(admission.Create, admission.Update), kclient: kclient, }, nil } func (q *restrictUsersAdmission) SetOpenshiftClient(c oclient.Interface) { q.oclient = c } func (q *restrictUsersAdmission) SetGroupCache(c *usercache.GroupCache) {