func ValidateProjectConfig(config api.ProjectConfig) ValidationResults { validationResults := ValidationResults{} if _, _, err := api.ParseNamespaceAndName(config.ProjectRequestTemplate); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("projectRequestTemplate", config.ProjectRequestTemplate, "must be in the form: namespace/templateName")) } if len(config.DefaultNodeSelector) > 0 { _, err := labelselector.Parse(config.DefaultNodeSelector) if err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("defaultNodeSelector", config.DefaultNodeSelector, "must be a valid label selector")) } } if alloc := config.SecurityAllocator; alloc != nil { if _, err := uid.ParseRange(alloc.UIDAllocatorRange); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("securityAllocator.uidAllocatorRange", alloc.UIDAllocatorRange, err.Error())) } if _, err := mcs.ParseRange(alloc.MCSAllocatorRange); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("securityAllocator.mcsAllocatorRange", alloc.MCSAllocatorRange, err.Error())) } if alloc.MCSLabelsPerProject <= 0 { validationResults.AddErrors(fielderrors.NewFieldInvalid("securityAllocator.mcsLabelsPerProject", alloc.MCSLabelsPerProject, "must be a positive integer")) } } else { validationResults.AddWarnings(fielderrors.NewFieldInvalid("securityAllocator", "null", "allocation of UIDs and MCS labels to a project must be done manually")) } return validationResults }
func ValidateProjectConfig(config api.ProjectConfig) fielderrors.ValidationErrorList { allErrs := fielderrors.ValidationErrorList{} if _, _, err := api.ParseNamespaceAndName(config.ProjectRequestTemplate); err != nil { allErrs = append(allErrs, fielderrors.NewFieldInvalid("projectRequestTemplate", config.ProjectRequestTemplate, "must be in the form: namespace/templateName")) } if len(config.DefaultNodeSelector) > 0 { _, err := labelselector.Parse(config.DefaultNodeSelector) if err != nil { allErrs = append(allErrs, fielderrors.NewFieldInvalid("defaultNodeSelector", config.DefaultNodeSelector, "must be a valid label selector")) } } if alloc := config.SecurityAllocator; alloc != nil { if _, err := uid.ParseRange(alloc.UIDAllocatorRange); err != nil { allErrs = append(allErrs, fielderrors.NewFieldInvalid("uidAllocatorRange", alloc.UIDAllocatorRange, err.Error())) } if _, err := mcs.ParseRange(alloc.MCSAllocatorRange); err != nil { allErrs = append(allErrs, fielderrors.NewFieldInvalid("mcsAllocatorRange", alloc.MCSAllocatorRange, err.Error())) } if alloc.MCSLabelsPerProject <= 0 { allErrs = append(allErrs, fielderrors.NewFieldInvalid("mcsLabelsPerProject", alloc.MCSLabelsPerProject, "must be a positive integer")) } } return allErrs }
// RunSecurityAllocationController starts the security allocation controller process. func (c *MasterConfig) RunSecurityAllocationController() { alloc := c.Options.ProjectConfig.SecurityAllocator if alloc == nil { glog.V(3).Infof("Security allocator is disabled - no UIDs assigned to projects") return } // TODO: move range initialization to run_config uidRange, err := uid.ParseRange(alloc.UIDAllocatorRange) if err != nil { glog.Fatalf("Unable to describe UID range: %v", err) } opts, err := c.RESTOptionsGetter.GetRESTOptions(unversioned.GroupResource{Resource: "securityuidranges"}) if err != nil { glog.Fatalf("Unable to load storage options for security UID ranges") } var etcdAlloc *etcdallocator.Etcd uidAllocator := uidallocator.New(uidRange, func(max int, rangeSpec string) allocator.Interface { mem := allocator.NewContiguousAllocationMap(max, rangeSpec) etcdAlloc = etcdallocator.NewEtcd(mem, "/ranges/uids", kapi.Resource("uidallocation"), opts.StorageConfig) return etcdAlloc }) mcsRange, err := mcs.ParseRange(alloc.MCSAllocatorRange) if err != nil { glog.Fatalf("Unable to describe MCS category range: %v", err) } kclient := c.SecurityAllocationControllerClient() repair := securitycontroller.NewRepair(time.Minute, kclient.Namespaces(), uidRange, etcdAlloc) if err := repair.RunOnce(); err != nil { // TODO: v scary, may need to use direct etcd calls? // If the security controller fails during RunOnce it could mean a // couple of things: // 1. an unexpected etcd error occurred getting an allocator or the namespaces // 2. the allocation blocks were full - would result in an admission controller that is unable // to create the strategies correctly which would likely mean that the cluster // would not admit pods the the majority of users. // 3. an unexpected error persisting an allocation for a namespace has occurred - same as above // In all cases we do not want to continue normal operations, this should be fatal. glog.Fatalf("Unable to initialize namespaces: %v", err) } factory := securitycontroller.AllocationFactory{ UIDAllocator: uidAllocator, MCSAllocator: securitycontroller.DefaultMCSAllocation(uidRange, mcsRange, alloc.MCSLabelsPerProject), Client: kclient.Namespaces(), // TODO: reuse namespace cache } controller := factory.Create() controller.Run() }
// RunSecurityAllocationController starts the security allocation controller process. func (c *MasterConfig) RunSecurityAllocationController() { alloc := c.Options.ProjectConfig.SecurityAllocator if alloc == nil { glog.V(3).Infof("Security allocator is disabled - no UIDs assigned to projects") return } // TODO: move range initialization to run_config uidRange, err := uid.ParseRange(alloc.UIDAllocatorRange) if err != nil { glog.Fatalf("Unable to describe UID range: %v", err) } var etcdAlloc *etcdallocator.Etcd uidAllocator := uidallocator.New(uidRange, func(max int, rangeSpec string) allocator.Interface { mem := allocator.NewContiguousAllocationMap(max, rangeSpec) etcdAlloc = etcdallocator.NewEtcd(mem, "/ranges/uids", "uidallocation", c.EtcdHelper) return etcdAlloc }) mcsRange, err := mcs.ParseRange(alloc.MCSAllocatorRange) if err != nil { glog.Fatalf("Unable to describe MCS category range: %v", err) } kclient := c.SecurityAllocationControllerClient() repair := securitycontroller.NewRepair(time.Minute, kclient.Namespaces(), uidRange, etcdAlloc) if err := repair.RunOnce(); err != nil { // TODO: v scary, may need to use direct etcd calls? glog.Fatalf("Unable to initialize namespaces: %v", err) } factory := securitycontroller.AllocationFactory{ UIDAllocator: uidAllocator, MCSAllocator: securitycontroller.DefaultMCSAllocation(uidRange, mcsRange, alloc.MCSLabelsPerProject), Client: kclient.Namespaces(), // TODO: reuse namespace cache } controller := factory.Create() controller.Run() }