func TestSnapshot(t *testing.T) { pr, err := util.ParsePortRange("10000-10200") if err != nil { t.Fatal(err) } r := NewPortAllocator(*pr) ports := []int{} for i := 0; i < 10; i++ { port, err := r.AllocateNext() if err != nil { t.Fatal(err) } ports = append(ports, port) } var dst api.RangeAllocation err = r.Snapshot(&dst) if err != nil { t.Fatal(err) } pr2, err := util.ParsePortRange(dst.Range) if err != nil { t.Fatal(err) } if pr.String() != pr2.String() { t.Fatalf("mismatched networks: %s : %s", pr, pr2) } otherPr, err := util.ParsePortRange("200-300") if err != nil { t.Fatal(err) } other := NewPortAllocator(*otherPr) if err := r.Restore(*otherPr, dst.Data); err != ErrMismatchedNetwork { t.Fatal(err) } other = NewPortAllocator(*pr2) if err := other.Restore(*pr2, dst.Data); err != nil { t.Fatal(err) } for _, n := range ports { if !other.Has(n) { t.Errorf("restored range does not have %s", n) } } if other.Free() != r.Free() { t.Errorf("counts do not match: %d", other.Free()) } }
func ValidateKubernetesMasterConfig(config *api.KubernetesMasterConfig) ValidationResults { validationResults := ValidationResults{} if len(config.MasterIP) > 0 { validationResults.AddErrors(ValidateSpecifiedIP(config.MasterIP, "masterIP")...) } if config.MasterCount < 1 { validationResults.AddErrors(fielderrors.NewFieldInvalid("masterCount", config.MasterCount, "must be a positive integer")) } if len(config.ServicesSubnet) > 0 { if _, _, err := net.ParseCIDR(strings.TrimSpace(config.ServicesSubnet)); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("servicesSubnet", config.ServicesSubnet, "must be a valid CIDR notation IP range (e.g. 172.30.0.0/16)")) } } if len(config.ServicesNodePortRange) > 0 { if _, err := util.ParsePortRange(strings.TrimSpace(config.ServicesNodePortRange)); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("servicesNodePortRange", config.ServicesNodePortRange, "must be a valid port range (e.g. 30000-32000)")) } } if len(config.SchedulerConfigFile) > 0 { validationResults.AddErrors(ValidateFile(config.SchedulerConfigFile, "schedulerConfigFile")...) } for i, nodeName := range config.StaticNodeNames { if len(nodeName) == 0 { validationResults.AddErrors(fielderrors.NewFieldInvalid(fmt.Sprintf("staticNodeName[%d]", i), nodeName, "may not be empty")) } } if len(config.PodEvictionTimeout) > 0 { if _, err := time.ParseDuration(config.PodEvictionTimeout); err != nil { validationResults.AddErrors(fielderrors.NewFieldInvalid("podEvictionTimeout", config.PodEvictionTimeout, "must be a valid time duration string (e.g. '300ms' or '2m30s'). Valid time units are 'ns', 'us', 'ms', 's', 'm', 'h'")) } } validationResults.Append(ValidateAPILevels(config.APILevels, api.KnownKubernetesAPILevels, api.DeadKubernetesAPILevels, "apiLevels")) validationResults.AddErrors(ValidateAPIServerExtendedArguments(config.APIServerArguments).Prefix("apiServerArguments")...) validationResults.AddErrors(ValidateControllerExtendedArguments(config.ControllerArguments).Prefix("controllerArguments")...) return validationResults }
func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextMapper kapi.RequestContextMapper, kubeClient *kclient.Client) (*MasterConfig, error) { if options.KubernetesMasterConfig == nil { return nil, errors.New("insufficient information to build KubernetesMasterConfig") } // Connect and setup etcd interfaces etcdClient, err := etcd.GetAndTestEtcdClient(options.EtcdClientInfo) if err != nil { return nil, err } ketcdHelper, err := master.NewEtcdHelper(etcdClient, options.EtcdStorageConfig.KubernetesStorageVersion, options.EtcdStorageConfig.KubernetesStoragePrefix) if err != nil { return nil, fmt.Errorf("Error setting up Kubernetes server storage: %v", err) } kubeletClientConfig := configapi.GetKubeletClientConfig(options) kubeletClient, err := kclient.NewKubeletClient(kubeletClientConfig) if err != nil { return nil, fmt.Errorf("unable to configure Kubelet client: %v", err) } // in-order list of plug-ins that should intercept admission decisions // TODO: Push node environment support to upstream in future _, portString, err := net.SplitHostPort(options.ServingInfo.BindAddress) if err != nil { return nil, err } port, err := strconv.Atoi(portString) if err != nil { return nil, err } portRange, err := util.ParsePortRange(options.KubernetesMasterConfig.ServicesNodePortRange) if err != nil { return nil, err } podEvictionTimeout, err := time.ParseDuration(options.KubernetesMasterConfig.PodEvictionTimeout) if err != nil { return nil, fmt.Errorf("unable to parse PodEvictionTimeout: %v", err) } server := app.NewAPIServer() server.EventTTL = 2 * time.Hour server.PortalNet = util.IPNet(flagtypes.DefaultIPNet(options.KubernetesMasterConfig.ServicesSubnet)) server.ServiceNodePorts = *portRange server.AdmissionControl = strings.Join([]string{ "NamespaceExists", "NamespaceLifecycle", "OriginPodNodeEnvironment", "LimitRanger", "ServiceAccount", "SecurityContextConstraint", "ResourceQuota", }, ",") // resolve extended arguments // TODO: this should be done in config validation (along with the above) so we can provide // proper errors if err := cmdflags.Resolve(options.KubernetesMasterConfig.APIServerArguments, server.AddFlags); len(err) > 0 { return nil, kerrors.NewAggregate(err) } cmserver := cmapp.NewCMServer() cmserver.PodEvictionTimeout = podEvictionTimeout // resolve extended arguments // TODO: this should be done in config validation (along with the above) so we can provide // proper errors if err := cmdflags.Resolve(options.KubernetesMasterConfig.ControllerArguments, cmserver.AddFlags); len(err) > 0 { return nil, kerrors.NewAggregate(err) } cloud, err := cloudprovider.InitCloudProvider(cmserver.CloudProvider, cmserver.CloudConfigFile) if err != nil { return nil, err } admissionController := admission.NewFromPlugins(kubeClient, strings.Split(server.AdmissionControl, ","), server.AdmissionControlConfigFile) m := &master.Config{ PublicAddress: net.ParseIP(options.KubernetesMasterConfig.MasterIP), ReadWritePort: port, ReadOnlyPort: port, EtcdHelper: ketcdHelper, EventTTL: server.EventTTL, //MinRequestTimeout: server.MinRequestTimeout, PortalNet: (*net.IPNet)(&server.PortalNet), ServiceNodePorts: server.ServiceNodePorts, RequestContextMapper: requestContextMapper, KubeletClient: kubeletClient, APIPrefix: KubeAPIPrefix, EnableCoreControllers: true, MasterCount: options.KubernetesMasterConfig.MasterCount, Authorizer: apiserver.NewAlwaysAllowAuthorizer(), AdmissionControl: admissionController, DisableV1Beta1: true, DisableV1Beta2: true, DisableV1Beta3: !configapi.HasKubernetesAPILevel(*options.KubernetesMasterConfig, "v1beta3"), EnableV1: configapi.HasKubernetesAPILevel(*options.KubernetesMasterConfig, "v1"), } kmaster := &MasterConfig{ Options: *options.KubernetesMasterConfig, KubeClient: kubeClient, Master: m, ControllerManager: cmserver, CloudProvider: cloud, } return kmaster, nil }
func TestAllocate(t *testing.T) { pr, err := util.ParsePortRange("10000-10200") if err != nil { t.Fatal(err) } r := NewPortAllocator(*pr) if f := r.Free(); f != 201 { t.Errorf("unexpected free %d", f) } found := util.NewStringSet() count := 0 for r.Free() > 0 { p, err := r.AllocateNext() if err != nil { t.Fatalf("error @ %d: %v", count, err) } count++ if !pr.Contains(p) { t.Fatalf("allocated %s which is outside of %s", p, pr) } if found.Has(strconv.Itoa(p)) { t.Fatalf("allocated %s twice @ %d", p, count) } found.Insert(strconv.Itoa(p)) } if _, err := r.AllocateNext(); err != ErrFull { t.Fatal(err) } released := 10005 if err := r.Release(released); err != nil { t.Fatal(err) } if f := r.Free(); f != 1 { t.Errorf("unexpected free %d", f) } p, err := r.AllocateNext() if err != nil { t.Fatal(err) } if released != p { t.Errorf("unexpected %s : %s", p, released) } if err := r.Release(released); err != nil { t.Fatal(err) } if err := r.Allocate(1); err != ErrNotInRange { t.Fatal(err) } if err := r.Allocate(10001); err != ErrAllocated { t.Fatal(err) } if err := r.Allocate(20000); err != ErrNotInRange { t.Fatal(err) } if err := r.Allocate(10201); err != ErrNotInRange { t.Fatal(err) } if f := r.Free(); f != 1 { t.Errorf("unexpected free %d", f) } if err := r.Allocate(released); err != nil { t.Fatal(err) } if f := r.Free(); f != 0 { t.Errorf("unexpected free %d", f) } }