// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. func (c *Config) Complete() completedConfig { if c.ServiceClusterIPRange == nil { defaultNet := "10.0.0.0/24" glog.Warningf("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet) _, serviceClusterIPRange, err := net.ParseCIDR(defaultNet) if err != nil { glog.Fatalf("Unable to parse CIDR: %v", err) } if size := ipallocator.RangeSize(serviceClusterIPRange); size < 8 { glog.Fatalf("The service cluster IP range must be at least %d IP addresses", 8) } c.ServiceClusterIPRange = serviceClusterIPRange } if c.ServiceReadWriteIP == nil { // Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP. serviceReadWriteIP, err := ipallocator.GetIndexedIP(c.ServiceClusterIPRange, 1) if err != nil { glog.Fatalf("Failed to generate service read-write IP for GenericAPIServer service: %v", err) } glog.V(4).Infof("Setting GenericAPIServer service IP to %q (read-write).", serviceReadWriteIP) c.ServiceReadWriteIP = serviceReadWriteIP } if c.ServiceReadWritePort == 0 { c.ServiceReadWritePort = 443 } if c.ServiceNodePortRange.Size == 0 { // TODO: Currently no way to specify an empty range (do we need to allow this?) // We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE) // but then that breaks the strict nestedness of ServiceType. // Review post-v1 c.ServiceNodePortRange = options.DefaultServiceNodePortRange glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange) } if c.MasterCount == 0 { // Clearly, there will be at least one GenericAPIServer. c.MasterCount = 1 } if c.ReadWritePort == 0 { c.ReadWritePort = 6443 } if c.CacheTimeout == 0 { c.CacheTimeout = 5 * time.Second } if c.RequestContextMapper == nil { c.RequestContextMapper = api.NewRequestContextMapper() } if len(c.ExternalHost) == 0 && c.PublicAddress != nil { hostAndPort := c.PublicAddress.String() if c.ReadWritePort != 0 { hostAndPort = net.JoinHostPort(hostAndPort, strconv.Itoa(c.ReadWritePort)) } c.ExternalHost = hostAndPort } if c.BuildHandlerChainsFunc == nil { c.BuildHandlerChainsFunc = DefaultBuildHandlerChain } return completedConfig{c} }
// DefaultServiceIPRange takes a the serviceIPRange flag and returns the defaulted service ip range (if needed), // api server service IP, and an error // TODO move this out of the genericapiserver package func DefaultServiceIPRange(passedServiceClusterIPRange net.IPNet) (net.IPNet, net.IP, error) { serviceClusterIPRange := passedServiceClusterIPRange if passedServiceClusterIPRange.IP == nil { defaultNet := "10.0.0.0/24" glog.Infof("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet) _, defaultServiceClusterIPRange, err := net.ParseCIDR(defaultNet) if err != nil { return net.IPNet{}, net.IP{}, err } serviceClusterIPRange = *defaultServiceClusterIPRange } if size := ipallocator.RangeSize(&serviceClusterIPRange); size < 8 { return net.IPNet{}, net.IP{}, fmt.Errorf("The service cluster IP range must be at least %d IP addresses", 8) } // Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP. apiServerServiceIP, err := ipallocator.GetIndexedIP(&serviceClusterIPRange, 1) if err != nil { return net.IPNet{}, net.IP{}, err } glog.V(4).Infof("Setting service IP to %q (read-write).", apiServerServiceIP) return serviceClusterIPRange, apiServerServiceIP, nil }
// Complete fills in any fields not set that are required to have valid data and can be derived // from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver. func (c *Config) Complete() completedConfig { if c.ServiceClusterIPRange == nil || c.ServiceClusterIPRange.IP == nil { defaultNet := "10.0.0.0/24" glog.Warningf("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet) _, serviceClusterIPRange, err := net.ParseCIDR(defaultNet) if err != nil { glog.Fatalf("Unable to parse CIDR: %v", err) } if size := ipallocator.RangeSize(serviceClusterIPRange); size < 8 { glog.Fatalf("The service cluster IP range must be at least %d IP addresses", 8) } c.ServiceClusterIPRange = serviceClusterIPRange } if c.ServiceReadWriteIP == nil { // Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP. serviceReadWriteIP, err := ipallocator.GetIndexedIP(c.ServiceClusterIPRange, 1) if err != nil { glog.Fatalf("Failed to generate service read-write IP for GenericAPIServer service: %v", err) } glog.V(4).Infof("Setting GenericAPIServer service IP to %q (read-write).", serviceReadWriteIP) c.ServiceReadWriteIP = serviceReadWriteIP } if c.ServiceNodePortRange.Size == 0 { // TODO: Currently no way to specify an empty range (do we need to allow this?) // We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE) // but then that breaks the strict nestedness of ServiceType. // Review post-v1 c.ServiceNodePortRange = options.DefaultServiceNodePortRange glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange) } if len(c.ExternalHost) == 0 && c.PublicAddress != nil { hostAndPort := c.PublicAddress.String() if c.ReadWritePort != 0 { hostAndPort = net.JoinHostPort(hostAndPort, strconv.Itoa(c.ReadWritePort)) } c.ExternalHost = hostAndPort } // All APIs will have the same authentication for now. if c.OpenAPIConfig != nil && c.OpenAPIConfig.SecurityDefinitions != nil { c.OpenAPIConfig.DefaultSecurity = []map[string][]string{} keys := []string{} for k := range *c.OpenAPIConfig.SecurityDefinitions { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { c.OpenAPIConfig.DefaultSecurity = append(c.OpenAPIConfig.DefaultSecurity, map[string][]string{k: {}}) } if c.OpenAPIConfig.CommonResponses == nil { c.OpenAPIConfig.CommonResponses = map[int]spec.Response{} } if _, exists := c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized]; !exists { c.OpenAPIConfig.CommonResponses[http.StatusUnauthorized] = spec.Response{ ResponseProps: spec.ResponseProps{ Description: "Unauthorized", }, } } } return completedConfig{c} }