// ValidateClusterWithDuration runs validation.ValidateCluster until either we get positive result or the timeout expires
181440
func (r *RollingUpdateInstanceGroup) ValidateClusterWithDuration(rollingUpdateData *RollingUpdateCluster, cluster *api.Cluster, instanceGroupList *api.InstanceGroupList, duration time.Duration) error {
	// TODO should we expose this to the UI?
	tickDuration := 30 * time.Second
	// Try to validate cluster at least once, this will handle durations that are lower
	// than our tick time
	if r.tryValidateCluster(rollingUpdateData, cluster, instanceGroupList, duration, tickDuration) {
		return nil
	}

	timeout := time.After(duration)
	tick := time.Tick(tickDuration)
	// Keep trying until we're timed out or got a result or got an error
	for {
		select {
		case <-timeout:
			// Got a timeout fail with a timeout error
			return fmt.Errorf("cluster did not validate within a duration of %q", duration)
		case <-tick:
			// Got a tick, validate cluster
			if r.tryValidateCluster(rollingUpdateData, cluster, instanceGroupList, duration, tickDuration) {
				return nil
			}
			// ValidateCluster didn't work yet, so let's try again
			// this will exit up to the for loop
		}
	}
}
1163904
func validateCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, ip string, apiserverPort int) {
	console.OutStyle("verifying-noline", "Verifying component health ...")
	k8sStat := func() (err error) {
		st, err := bs.GetKubeletStatus()
		console.Out(".")
		if err != nil || st != state.Running.String() {
			return &pkgutil.RetriableError{Err: fmt.Errorf("kubelet unhealthy: %v: %s", err, st)}
		}
		return nil
	}
	err := pkgutil.RetryAfter(20, k8sStat, 3*time.Second)
	if err != nil {
		exit.WithLogEntries("kubelet checks failed", err, logs.FindProblems(r, bs, runner))
	}
	aStat := func() (err error) {
		st, err := bs.GetAPIServerStatus(net.ParseIP(ip), apiserverPort)
		console.Out(".")
		if err != nil || st != state.Running.String() {
			return &pkgutil.RetriableError{Err: fmt.Errorf("apiserver status=%s err=%v", st, err)}
		}
		return nil
	}

	err = pkgutil.RetryAfter(30, aStat, 10*time.Second)
	if err != nil {
		exit.WithLogEntries("apiserver checks failed", err, logs.FindProblems(r, bs, runner))
	}
	console.OutLn("")
}
431909
func (o *GetPrefilterParams) WithTimeout(timeout time.Duration) *GetPrefilterParams {
	o.SetTimeout(timeout)
	return o
}
829651
func (builder *ListBucketsCommandBuilder) WithTimeout(timeout time.Duration) *ListBucketsCommandBuilder {
	timeoutMilliseconds := uint32(timeout / time.Millisecond)
	builder.protobuf.Timeout = &timeoutMilliseconds
	return builder
}
950628
func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
	clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
	return validation.ValidateClusterRoleBinding(clusterRoleBinding)
}
65553
func (o *GetStatusParams) WithTimeout(timeout time.Duration) *GetStatusParams {
	o.SetTimeout(timeout)
	return o
}
639182
func (o *IsInstanceAliveParams) WithTimeout(timeout time.Duration) *IsInstanceAliveParams {
	o.SetTimeout(timeout)
	return o
}
762745
func (m *ClusterManager) Validate() error {
	if m == nil {
		return nil
	}

	// no validation rules for LocalClusterName

	{
		tmp := m.GetOutlierDetection()

		if v, ok := interface{}(tmp).(interface{ Validate() error }); ok {

			if err := v.Validate(); err != nil {
				return ClusterManagerValidationError{
					field:  "OutlierDetection",
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}
	}

	{
		tmp := m.GetUpstreamBindConfig()

		if v, ok := interface{}(tmp).(interface{ Validate() error }); ok {

			if err := v.Validate(); err != nil {
				return ClusterManagerValidationError{
					field:  "UpstreamBindConfig",
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}
	}

	{
		tmp := m.GetLoadStatsConfig()

		if v, ok := interface{}(tmp).(interface{ Validate() error }); ok {

			if err := v.Validate(); err != nil {
				return ClusterManagerValidationError{
					field:  "LoadStatsConfig",
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}
	}

	return nil
}
1276621
func (o *CreateParams) WithTimeout(timeout time.Duration) *CreateParams {
	o.SetTimeout(timeout)
	return o
}
1360671
func (o *Oauth2TokenParams) WithTimeout(timeout time.Duration) *Oauth2TokenParams {
	o.SetTimeout(timeout)
	return o
}
1115645
func (m *WeightedCluster_ClusterWeight) Validate() error {
	if m == nil {
		return nil
	}

	if len(m.GetName()) < 1 {
		return WeightedCluster_ClusterWeightValidationError{
			field:  "Name",
			reason: "value length must be at least 1 bytes",
		}
	}

	if wrapper := m.GetWeight(); wrapper != nil {

		if wrapper.GetValue() < 1 {
			return WeightedCluster_ClusterWeightValidationError{
				field:  "Weight",
				reason: "value must be greater than or equal to 1",
			}
		}

	}

	{
		tmp := m.GetMetadataMatch()

		if v, ok := interface{}(tmp).(interface{ Validate() error }); ok {

			if err := v.Validate(); err != nil {
				return WeightedCluster_ClusterWeightValidationError{
					field:  "MetadataMatch",
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}
	}

	return nil
}
879022
func (s SingularSecretary) CheckDuration(duration time.Duration) error {
	if duration <= 0 {
		return errors.NewNotValid(nil, "non-positive")
	}
	return nil
}
1079410
func (o *GetEndpointIDParams) WithTimeout(timeout time.Duration) *GetEndpointIDParams {
	o.SetTimeout(timeout)
	return o
}
1010072
func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
	fieldSpec := field.NewPath("spec")
	var err error

	// kubernetesRelease is the version with only major & minor fields
	var kubernetesRelease semver.Version

	// KubernetesVersion
	if c.Spec.KubernetesVersion == "" {
		return field.Required(fieldSpec.Child("KubernetesVersion"), "")
	}

	sv, err := util.ParseKubernetesVersion(c.Spec.KubernetesVersion)
	if err != nil {
		return field.Invalid(fieldSpec.Child("KubernetesVersion"), c.Spec.KubernetesVersion, "unable to determine kubernetes version")
	}
	kubernetesRelease = semver.Version{Major: sv.Major, Minor: sv.Minor}

	if c.ObjectMeta.Name == "" {
		return field.Required(field.NewPath("Name"), "Cluster Name is required (e.g. --name=mycluster.myzone.com)")
	}

	{
		// Must be a dns name
		errs := validation.IsDNS1123Subdomain(c.ObjectMeta.Name)
		if len(errs) != 0 {
			return field.Invalid(field.NewPath("Name"), c.ObjectMeta.Name, fmt.Sprintf("Cluster Name must be a valid DNS name (e.g. --name=mycluster.myzone.com) errors: %s", strings.Join(errs, ", ")))
		}

		if !strings.Contains(c.ObjectMeta.Name, ".") {
			// Tolerate if this is a cluster we are importing for upgrade
			if c.ObjectMeta.Annotations[kops.AnnotationNameManagement] != kops.AnnotationValueManagementImported {
				return field.Invalid(field.NewPath("Name"), c.ObjectMeta.Name, "Cluster Name must be a fully-qualified DNS name (e.g. --name=mycluster.myzone.com)")
			}
		}
	}

	if c.Spec.Assets != nil && c.Spec.Assets.ContainerProxy != nil && c.Spec.Assets.ContainerRegistry != nil {
		return field.Forbidden(fieldSpec.Child("Assets", "ContainerProxy"), "ContainerProxy cannot be used in conjunction with ContainerRegistry as represent mutually exclusive concepts. Please consult the documentation for details.")
	}

	if c.Spec.CloudProvider == "" {
		return field.Required(fieldSpec.Child("CloudProvider"), "")
	}

	requiresSubnets := true
	requiresNetworkCIDR := true
	requiresSubnetCIDR := true
	switch kops.CloudProviderID(c.Spec.CloudProvider) {
	case kops.CloudProviderBareMetal:
		requiresSubnets = false
		requiresSubnetCIDR = false
		requiresNetworkCIDR = false
		if c.Spec.NetworkCIDR != "" {
			return field.Invalid(fieldSpec.Child("NetworkCIDR"), c.Spec.NetworkCIDR, "NetworkCIDR should not be set on bare metal")
		}

	case kops.CloudProviderGCE:
		requiresNetworkCIDR = false
		if c.Spec.NetworkCIDR != "" {
			return field.Invalid(fieldSpec.Child("NetworkCIDR"), c.Spec.NetworkCIDR, "NetworkCIDR should not be set on GCE")
		}
		requiresSubnetCIDR = false

	case kops.CloudProviderDO:
		requiresSubnets = false
		requiresSubnetCIDR = false
		requiresNetworkCIDR = false
		if c.Spec.NetworkCIDR != "" {
			return field.Invalid(fieldSpec.Child("NetworkCIDR"), c.Spec.NetworkCIDR, "NetworkCIDR should not be set on DigitalOcean")
		}
	case kops.CloudProviderALI:
		requiresSubnets = false
		requiresSubnetCIDR = false
		requiresNetworkCIDR = false
	case kops.CloudProviderAWS:
	case kops.CloudProviderVSphere:
	case kops.CloudProviderOpenstack:
		requiresNetworkCIDR = false
		requiresSubnetCIDR = false

	default:
		return field.Invalid(fieldSpec.Child("CloudProvider"), c.Spec.CloudProvider, "CloudProvider not recognized")
	}

	if requiresSubnets && len(c.Spec.Subnets) == 0 {
		// TODO: Auto choose zones from region?
		return field.Required(fieldSpec.Child("Subnets"), "must configure at least one Subnet (use --zones)")
	}

	if strict && c.Spec.Kubelet == nil {
		return field.Required(fieldSpec.Child("Kubelet"), "Kubelet not configured")
	}
	if strict && c.Spec.MasterKubelet == nil {
		return field.Required(fieldSpec.Child("MasterKubelet"), "MasterKubelet not configured")
	}
	if strict && c.Spec.KubeControllerManager == nil {
		return field.Required(fieldSpec.Child("KubeControllerManager"), "KubeControllerManager not configured")
	}
	if kubernetesRelease.LT(semver.MustParse("1.7.0")) && c.Spec.ExternalCloudControllerManager != nil {
		return field.Invalid(fieldSpec.Child("ExternalCloudControllerManager"), c.Spec.ExternalCloudControllerManager, "ExternalCloudControllerManager is not supported in version 1.6.0 or lower")
	}
	if strict && c.Spec.KubeDNS == nil {
		return field.Required(fieldSpec.Child("KubeDNS"), "KubeDNS not configured")
	}
	if strict && c.Spec.KubeScheduler == nil {
		return field.Required(fieldSpec.Child("KubeScheduler"), "KubeScheduler not configured")
	}
	if strict && c.Spec.KubeAPIServer == nil {
		return field.Required(fieldSpec.Child("KubeAPIServer"), "KubeAPIServer not configured")
	}
	if strict && c.Spec.KubeProxy == nil {
		return field.Required(fieldSpec.Child("KubeProxy"), "KubeProxy not configured")
	}
	if strict && c.Spec.Docker == nil {
		return field.Required(fieldSpec.Child("Docker"), "Docker not configured")
	}

	// Check NetworkCIDR
	var networkCIDR *net.IPNet
	{
		if c.Spec.NetworkCIDR == "" {
			if requiresNetworkCIDR {
				return field.Required(fieldSpec.Child("NetworkCIDR"), "Cluster did not have NetworkCIDR set")
			}
		} else {
			_, networkCIDR, err = net.ParseCIDR(c.Spec.NetworkCIDR)
			if err != nil {
				return field.Invalid(fieldSpec.Child("NetworkCIDR"), c.Spec.NetworkCIDR, fmt.Sprintf("Cluster had an invalid NetworkCIDR"))
			}
		}
	}

	// Check AdditionalNetworkCIDRs
	var additionalNetworkCIDRs []*net.IPNet
	{
		if len(c.Spec.AdditionalNetworkCIDRs) > 0 {
			for _, AdditionalNetworkCIDR := range c.Spec.AdditionalNetworkCIDRs {
				_, IPNetAdditionalNetworkCIDR, err := net.ParseCIDR(AdditionalNetworkCIDR)
				if err != nil {
					return field.Invalid(fieldSpec.Child("AdditionalNetworkCIDRs"), AdditionalNetworkCIDR, fmt.Sprintf("Cluster had an invalid AdditionalNetworkCIDRs"))
				}
				additionalNetworkCIDRs = append(additionalNetworkCIDRs, IPNetAdditionalNetworkCIDR)
			}
		}
	}

	// Check NonMasqueradeCIDR
	var nonMasqueradeCIDR *net.IPNet
	{
		nonMasqueradeCIDRString := c.Spec.NonMasqueradeCIDR
		if nonMasqueradeCIDRString == "" {
			return field.Required(fieldSpec.Child("NonMasqueradeCIDR"), "Cluster did not have NonMasqueradeCIDR set")
		}
		_, nonMasqueradeCIDR, err = net.ParseCIDR(nonMasqueradeCIDRString)
		if err != nil {
			return field.Invalid(fieldSpec.Child("NonMasqueradeCIDR"), nonMasqueradeCIDRString, "Cluster had an invalid NonMasqueradeCIDR")
		}

		if networkCIDR != nil && subnet.Overlap(nonMasqueradeCIDR, networkCIDR) && c.Spec.Networking != nil && c.Spec.Networking.AmazonVPC == nil && c.Spec.Networking.LyftVPC == nil {

			return field.Invalid(fieldSpec.Child("NonMasqueradeCIDR"), nonMasqueradeCIDRString, fmt.Sprintf("NonMasqueradeCIDR %q cannot overlap with NetworkCIDR %q", nonMasqueradeCIDRString, c.Spec.NetworkCIDR))
		}

		if c.Spec.Kubelet != nil && c.Spec.Kubelet.NonMasqueradeCIDR != nonMasqueradeCIDRString {
			if strict || c.Spec.Kubelet.NonMasqueradeCIDR != "" {
				return field.Invalid(fieldSpec.Child("NonMasqueradeCIDR"), nonMasqueradeCIDRString, "Kubelet NonMasqueradeCIDR did not match cluster NonMasqueradeCIDR")
			}
		}
		if c.Spec.MasterKubelet != nil && c.Spec.MasterKubelet.NonMasqueradeCIDR != nonMasqueradeCIDRString {
			if strict || c.Spec.MasterKubelet.NonMasqueradeCIDR != "" {
				return field.Invalid(fieldSpec.Child("NonMasqueradeCIDR"), nonMasqueradeCIDRString, "MasterKubelet NonMasqueradeCIDR did not match cluster NonMasqueradeCIDR")
			}
		}
	}

	// Check ServiceClusterIPRange
	var serviceClusterIPRange *net.IPNet
	{
		serviceClusterIPRangeString := c.Spec.ServiceClusterIPRange
		if serviceClusterIPRangeString == "" {
			if strict {
				return field.Required(fieldSpec.Child("ServiceClusterIPRange"), "Cluster did not have ServiceClusterIPRange set")
			}
		} else {
			_, serviceClusterIPRange, err = net.ParseCIDR(serviceClusterIPRangeString)
			if err != nil {
				return field.Invalid(fieldSpec.Child("ServiceClusterIPRange"), serviceClusterIPRangeString, "Cluster had an invalid ServiceClusterIPRange")
			}

			if !subnet.BelongsTo(nonMasqueradeCIDR, serviceClusterIPRange) {
				return field.Invalid(fieldSpec.Child("ServiceClusterIPRange"), serviceClusterIPRangeString, fmt.Sprintf("ServiceClusterIPRange %q must be a subnet of NonMasqueradeCIDR %q", serviceClusterIPRangeString, c.Spec.NonMasqueradeCIDR))
			}

			if c.Spec.KubeAPIServer != nil && c.Spec.KubeAPIServer.ServiceClusterIPRange != serviceClusterIPRangeString {
				if strict || c.Spec.KubeAPIServer.ServiceClusterIPRange != "" {
					return field.Invalid(fieldSpec.Child("ServiceClusterIPRange"), serviceClusterIPRangeString, "KubeAPIServer ServiceClusterIPRange did not match cluster ServiceClusterIPRange")
				}
			}
		}
	}

	// Check Canal Networking Spec if used
	if c.Spec.Networking != nil && c.Spec.Networking.Canal != nil {
		action := c.Spec.Networking.Canal.DefaultEndpointToHostAction
		switch action {
		case "", "ACCEPT", "DROP", "RETURN":
		default:
			return field.Invalid(fieldSpec.Child("Networking", "Canal", "DefaultEndpointToHostAction"), action, fmt.Sprintf("Unsupported value: %s, supports 'ACCEPT', 'DROP' or 'RETURN'", action))
		}

		chainInsertMode := c.Spec.Networking.Canal.ChainInsertMode
		switch chainInsertMode {
		case "", "insert", "append":
		default:
			return field.Invalid(fieldSpec.Child("Networking", "Canal", "ChainInsertMode"), chainInsertMode, fmt.Sprintf("Unsupported value: %s, supports 'insert' or 'append'", chainInsertMode))
		}

		logSeveritySys := c.Spec.Networking.Canal.LogSeveritySys
		switch logSeveritySys {
		case "", "INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL", "NONE":
		default:
			return field.Invalid(fieldSpec.Child("Networking", "Canal", "LogSeveritySys"), logSeveritySys, fmt.Sprintf("Unsupported value: %s, supports 'INFO', 'DEBUG', 'WARNING', 'ERROR', 'CRITICAL' or 'NONE'", logSeveritySys))
		}
	}

	// Check ClusterCIDR
	if c.Spec.KubeControllerManager != nil {
		var clusterCIDR *net.IPNet
		clusterCIDRString := c.Spec.KubeControllerManager.ClusterCIDR
		if clusterCIDRString != "" {
			_, clusterCIDR, err = net.ParseCIDR(clusterCIDRString)
			if err != nil {
				return field.Invalid(fieldSpec.Child("KubeControllerManager", "ClusterCIDR"), clusterCIDRString, "Cluster had an invalid KubeControllerManager.ClusterCIDR")
			}

			if !subnet.BelongsTo(nonMasqueradeCIDR, clusterCIDR) {
				return field.Invalid(fieldSpec.Child("KubeControllerManager", "ClusterCIDR"), clusterCIDRString, fmt.Sprintf("KubeControllerManager.ClusterCIDR %q must be a subnet of NonMasqueradeCIDR %q", clusterCIDRString, c.Spec.NonMasqueradeCIDR))
			}
		}
	}

	// @check the custom kubedns options are valid
	if c.Spec.KubeDNS != nil {
		if c.Spec.KubeDNS.ServerIP != "" {
			address := c.Spec.KubeDNS.ServerIP
			ip := net.ParseIP(address)
			if ip == nil {
				return field.Invalid(fieldSpec.Child("kubeDNS", "serverIP"), address, "Cluster had an invalid kubeDNS.serverIP")
			}
			if serviceClusterIPRange != nil && !serviceClusterIPRange.Contains(ip) {
				return field.Invalid(fieldSpec.Child("kubeDNS", "serverIP"), address, fmt.Sprintf("ServiceClusterIPRange %q must contain the DNS Server IP %q", c.Spec.ServiceClusterIPRange, address))
			}
			if !featureflag.ExperimentalClusterDNS.Enabled() {
				if c.Spec.Kubelet != nil && c.Spec.Kubelet.ClusterDNS != c.Spec.KubeDNS.ServerIP {
					return field.Invalid(fieldSpec.Child("kubeDNS", "serverIP"), address, "Kubelet ClusterDNS did not match cluster kubeDNS.serverIP")
				}
				if c.Spec.MasterKubelet != nil && c.Spec.MasterKubelet.ClusterDNS != c.Spec.KubeDNS.ServerIP {
					return field.Invalid(fieldSpec.Child("kubeDNS", "serverIP"), address, "MasterKubelet ClusterDNS did not match cluster kubeDNS.serverIP")
				}
			}
		}

		// @check the nameservers are valid
		for i, x := range c.Spec.KubeDNS.UpstreamNameservers {
			if ip := net.ParseIP(x); ip == nil {
				return field.Invalid(fieldSpec.Child("kubeDNS", "upstreamNameservers").Index(i), x, "Invalid nameserver given, should be a valid ip address")
			}
		}

		// @check the stubdomain if any
		if c.Spec.KubeDNS.StubDomains != nil {
			for domain, nameservers := range c.Spec.KubeDNS.StubDomains {
				if len(nameservers) <= 0 {
					return field.Invalid(fieldSpec.Child("kubeDNS", "stubDomains").Key(domain), domain, "No nameservers specified for the stub domain")
				}
				for i, x := range nameservers {
					if ip := net.ParseIP(x); ip == nil {
						return field.Invalid(fieldSpec.Child("kubeDNS", "stubDomains").Key(domain).Index(i), x, "Invalid nameserver given, should be a valid ip address")
					}
				}
			}
		}
	}

	// Check CloudProvider
	{

		var k8sCloudProvider string
		switch kops.CloudProviderID(c.Spec.CloudProvider) {
		case kops.CloudProviderAWS:
			k8sCloudProvider = "aws"
		case kops.CloudProviderGCE:
			k8sCloudProvider = "gce"
		case kops.CloudProviderDO:
			k8sCloudProvider = "external"
		case kops.CloudProviderVSphere:
			k8sCloudProvider = "vsphere"
		case kops.CloudProviderBareMetal:
			k8sCloudProvider = ""
		case kops.CloudProviderOpenstack:
			k8sCloudProvider = "openstack"
		case kops.CloudProviderALI:
			k8sCloudProvider = "alicloud"
		default:
			return field.Invalid(fieldSpec.Child("CloudProvider"), c.Spec.CloudProvider, "unknown cloudprovider")
		}

		if c.Spec.Kubelet != nil && (strict || c.Spec.Kubelet.CloudProvider != "") {
			if c.Spec.Kubelet.CloudProvider != "external" && k8sCloudProvider != c.Spec.Kubelet.CloudProvider {
				return field.Invalid(fieldSpec.Child("Kubelet", "CloudProvider"), c.Spec.Kubelet.CloudProvider, "Did not match cluster CloudProvider")
			}
		}
		if c.Spec.MasterKubelet != nil && (strict || c.Spec.MasterKubelet.CloudProvider != "") {
			if c.Spec.MasterKubelet.CloudProvider != "external" && k8sCloudProvider != c.Spec.MasterKubelet.CloudProvider {
				return field.Invalid(fieldSpec.Child("MasterKubelet", "CloudProvider"), c.Spec.MasterKubelet.CloudProvider, "Did not match cluster CloudProvider")

			}
		}
		if c.Spec.KubeAPIServer != nil && (strict || c.Spec.KubeAPIServer.CloudProvider != "") {
			if c.Spec.KubeAPIServer.CloudProvider != "external" && k8sCloudProvider != c.Spec.KubeAPIServer.CloudProvider {
				return field.Invalid(fieldSpec.Child("KubeAPIServer", "CloudProvider"), c.Spec.KubeAPIServer.CloudProvider, "Did not match cluster CloudProvider")
			}
		}
		if c.Spec.KubeControllerManager != nil && (strict || c.Spec.KubeControllerManager.CloudProvider != "") {
			if c.Spec.KubeControllerManager.CloudProvider != "external" && k8sCloudProvider != c.Spec.KubeControllerManager.CloudProvider {
				return field.Invalid(fieldSpec.Child("KubeControllerManager", "CloudProvider"), c.Spec.KubeControllerManager.CloudProvider, "Did not match cluster CloudProvider")
			}
		}
	}

	// Check that the subnet CIDRs are all consistent
	{
		for i, s := range c.Spec.Subnets {
			fieldSubnet := fieldSpec.Child("Subnets").Index(i)
			if s.CIDR == "" {
				if requiresSubnetCIDR && strict {
					return field.Required(fieldSubnet.Child("CIDR"), "Subnet did not have a CIDR set")
				}
			} else {
				_, subnetCIDR, err := net.ParseCIDR(s.CIDR)
				if err != nil {
					return field.Invalid(fieldSubnet.Child("CIDR"), s.CIDR, "Subnet had an invalid CIDR")
				}

				if networkCIDR != nil && !validateSubnetCIDR(networkCIDR, additionalNetworkCIDRs, subnetCIDR) {
					return field.Invalid(fieldSubnet.Child("CIDR"), s.CIDR, fmt.Sprintf("Subnet %q had a CIDR %q that was not a subnet of the NetworkCIDR %q", s.Name, s.CIDR, c.Spec.NetworkCIDR))
				}
			}
		}
	}

	// NodeAuthorization
	if c.Spec.NodeAuthorization != nil {
		// @check the feature gate is enabled for this
		if !featureflag.EnableNodeAuthorization.Enabled() {
			return field.Invalid(field.NewPath("nodeAuthorization"), nil, "node authorization is experimental feature; set `export KOPS_FEATURE_FLAGS=EnableNodeAuthorization`")
		}
		if c.Spec.NodeAuthorization.NodeAuthorizer == nil {
			return field.Invalid(field.NewPath("nodeAuthorization"), nil, "no node authorization policy has been set")
		}
		// NodeAuthorizer
		if c.Spec.NodeAuthorization.NodeAuthorizer != nil {
			path := field.NewPath("nodeAuthorization").Child("nodeAuthorizer")
			if c.Spec.NodeAuthorization.NodeAuthorizer.Port < 0 || c.Spec.NodeAuthorization.NodeAuthorizer.Port >= 65535 {
				return field.Invalid(path.Child("port"), c.Spec.NodeAuthorization.NodeAuthorizer.Port, "invalid port")
			}
			if c.Spec.NodeAuthorization.NodeAuthorizer.Timeout != nil && c.Spec.NodeAuthorization.NodeAuthorizer.Timeout.Duration <= 0 {
				return field.Invalid(path.Child("timeout"), c.Spec.NodeAuthorization.NodeAuthorizer.Timeout, "must be greater than zero")
			}
			if c.Spec.NodeAuthorization.NodeAuthorizer.TokenTTL != nil && c.Spec.NodeAuthorization.NodeAuthorizer.TokenTTL.Duration < 0 {
				return field.Invalid(path.Child("tokenTTL"), c.Spec.NodeAuthorization.NodeAuthorizer.TokenTTL, "must be greater than or equal to zero")
			}

			// @question: we could probably just default theses settings in the model when the node-authorizer is enabled??
			if c.Spec.KubeAPIServer == nil {
				return field.Invalid(field.NewPath("kubeAPIServer"), c.Spec.KubeAPIServer, "bootstrap token authentication is not enabled in the kube-apiserver")
			}
			if c.Spec.KubeAPIServer.EnableBootstrapAuthToken == nil {
				return field.Invalid(field.NewPath("kubeAPIServer").Child("enableBootstrapAuthToken"), nil, "kube-apiserver has not been configured to use bootstrap tokens")
			}
			if !fi.BoolValue(c.Spec.KubeAPIServer.EnableBootstrapAuthToken) {
				return field.Invalid(field.NewPath("kubeAPIServer").Child("enableBootstrapAuthToken"),
					c.Spec.KubeAPIServer.EnableBootstrapAuthToken, "bootstrap tokens in the kube-apiserver has been disabled")
			}
		}
	}

	// UpdatePolicy
	if c.Spec.UpdatePolicy != nil {
		switch *c.Spec.UpdatePolicy {
		case kops.UpdatePolicyExternal:
		// Valid
		default:
			return field.Invalid(fieldSpec.Child("UpdatePolicy"), *c.Spec.UpdatePolicy, "unrecognized value for UpdatePolicy")
		}
	}

	// KubeProxy
	if c.Spec.KubeProxy != nil {
		ipvsMode := "ipvs"
		kubeProxyPath := fieldSpec.Child("KubeProxy")
		master := c.Spec.KubeProxy.Master

		if kubernetesRelease.LT(semver.MustParse("1.8.0")) && c.Spec.KubeProxy.ProxyMode == ipvsMode {
			return field.Invalid(kubeProxyPath.Child("proxyMode"), c.Spec.KubeProxy.ProxyMode, ipvsMode+" is not available pre v1.8.0")
		}
		for i, x := range c.Spec.KubeProxy.IPVSExcludeCIDRS {
			if _, _, err := net.ParseCIDR(x); err != nil {
				return field.Invalid(kubeProxyPath.Child("ipvsExcludeCIDRS").Index(i), x, "Invalid network CIDR")
			}
		}

		if master != "" && !isValidAPIServersURL(master) {
			return field.Invalid(kubeProxyPath.Child("Master"), master, "Not a valid APIServer URL")
		}
	}

	// KubeAPIServer
	if c.Spec.KubeAPIServer != nil {
		if kubernetesRelease.GTE(semver.MustParse("1.10.0")) {
			if len(c.Spec.KubeAPIServer.AdmissionControl) > 0 {
				if len(c.Spec.KubeAPIServer.DisableAdmissionPlugins) > 0 {
					return field.Invalid(fieldSpec.Child("KubeAPIServer").Child("DisableAdmissionPlugins"),
						strings.Join(c.Spec.KubeAPIServer.DisableAdmissionPlugins, ","),
						"DisableAdmissionPlugins is mutually exclusive, you cannot use both AdmissionControl and DisableAdmissionPlugins together")
				}
			}
		}
	}

	// Kubelet
	if c.Spec.Kubelet != nil {
		kubeletPath := fieldSpec.Child("Kubelet")

		if kubernetesRelease.GTE(semver.MustParse("1.6.0")) {
			// Flag removed in 1.6
			if c.Spec.Kubelet.APIServers != "" {
				return field.Invalid(
					kubeletPath.Child("APIServers"),
					c.Spec.Kubelet.APIServers,
					"api-servers flag was removed in 1.6")
			}
		} else {
			if strict && c.Spec.Kubelet.APIServers == "" {
				return field.Required(kubeletPath.Child("APIServers"), "")
			}
		}

		if kubernetesRelease.GTE(semver.MustParse("1.10.0")) {
			// Flag removed in 1.10
			if c.Spec.Kubelet.RequireKubeconfig != nil {
				return field.Invalid(
					kubeletPath.Child("requireKubeconfig"),
					*c.Spec.Kubelet.RequireKubeconfig,
					"require-kubeconfig flag was removed in 1.10.  (Please be sure you are not using a cluster config from `kops get cluster --full`)")
			}
		}

		if c.Spec.Kubelet.BootstrapKubeconfig != "" {
			if c.Spec.KubeAPIServer == nil {
				return field.Required(fieldSpec.Child("KubeAPIServer"), "bootstrap token require the NodeRestriction admissions controller")
			}
		}

		if c.Spec.Kubelet.APIServers != "" && !isValidAPIServersURL(c.Spec.Kubelet.APIServers) {
			return field.Invalid(kubeletPath.Child("APIServers"), c.Spec.Kubelet.APIServers, "Not a valid APIServer URL")
		}
	}

	// MasterKubelet
	if c.Spec.MasterKubelet != nil {
		masterKubeletPath := fieldSpec.Child("MasterKubelet")

		if kubernetesRelease.GTE(semver.MustParse("1.6.0")) {
			// Flag removed in 1.6
			if c.Spec.MasterKubelet.APIServers != "" {
				return field.Invalid(
					masterKubeletPath.Child("APIServers"),
					c.Spec.MasterKubelet.APIServers,
					"api-servers flag was removed in 1.6")
			}
		} else {
			if strict && c.Spec.MasterKubelet.APIServers == "" {
				return field.Required(masterKubeletPath.Child("APIServers"), "")
			}
		}

		if kubernetesRelease.GTE(semver.MustParse("1.10.0")) {
			// Flag removed in 1.10
			if c.Spec.MasterKubelet.RequireKubeconfig != nil {
				return field.Invalid(
					masterKubeletPath.Child("requireKubeconfig"),
					*c.Spec.MasterKubelet.RequireKubeconfig,
					"require-kubeconfig flag was removed in 1.10.  (Please be sure you are not using a cluster config from `kops get cluster --full`)")
			}
		}

		if c.Spec.MasterKubelet.APIServers != "" && !isValidAPIServersURL(c.Spec.MasterKubelet.APIServers) {
			return field.Invalid(masterKubeletPath.Child("APIServers"), c.Spec.MasterKubelet.APIServers, "Not a valid APIServer URL")
		}
	}

	// Topology support
	if c.Spec.Topology != nil {
		if c.Spec.Topology.Masters != "" && c.Spec.Topology.Nodes != "" {
			if c.Spec.Topology.Masters != kops.TopologyPublic && c.Spec.Topology.Masters != kops.TopologyPrivate {
				return field.Invalid(fieldSpec.Child("Topology", "Masters"), c.Spec.Topology.Masters, "Invalid Masters value for Topology")
			} else if c.Spec.Topology.Nodes != kops.TopologyPublic && c.Spec.Topology.Nodes != kops.TopologyPrivate {
				return field.Invalid(fieldSpec.Child("Topology", "Nodes"), c.Spec.Topology.Nodes, "Invalid Nodes value for Topology")
			}

		} else {
			return field.Required(fieldSpec.Child("Masters"), "Topology requires non-nil values for Masters and Nodes")
		}
		if c.Spec.Topology.Bastion != nil {
			bastion := c.Spec.Topology.Bastion
			if c.Spec.Topology.Masters == kops.TopologyPublic || c.Spec.Topology.Nodes == kops.TopologyPublic {
				return field.Invalid(fieldSpec.Child("Topology", "Masters"), c.Spec.Topology.Masters, "Bastion supports only Private Masters and Nodes")
			}
			if bastion.IdleTimeoutSeconds != nil && *bastion.IdleTimeoutSeconds <= 0 {
				return field.Invalid(fieldSpec.Child("Topology", "Bastion", "IdleTimeoutSeconds"), *bastion.IdleTimeoutSeconds, "Bastion IdleTimeoutSeconds should be greater than zero")
			}
			if bastion.IdleTimeoutSeconds != nil && *bastion.IdleTimeoutSeconds > 3600 {
				return field.Invalid(fieldSpec.Child("Topology", "Bastion", "IdleTimeoutSeconds"), *bastion.IdleTimeoutSeconds, "Bastion IdleTimeoutSeconds cannot be greater than one hour")
			}

		}
	}
	// Egress specification support
	{
		for i, s := range c.Spec.Subnets {
			if s.Egress == "" {
				continue
			}
			fieldSubnet := fieldSpec.Child("Subnets").Index(i)
			if !strings.HasPrefix(s.Egress, "nat-") && !strings.HasPrefix(s.Egress, "i-") && s.Egress != kops.EgressExternal {
				return field.Invalid(fieldSubnet.Child("Egress"), s.Egress, "egress must be of type NAT Gateway or NAT EC2 Instance or 'External'")
			}
			if s.Egress != kops.EgressExternal && s.Type != "Private" {
				return field.Invalid(fieldSubnet.Child("Egress"), s.Egress, "egress can only be specified for Private subnets")
			}
		}
	}

	// Etcd
	{
		fieldEtcdClusters := fieldSpec.Child("EtcdClusters")

		if len(c.Spec.EtcdClusters) == 0 {
			return field.Required(fieldEtcdClusters, "")
		}
		for i, x := range c.Spec.EtcdClusters {
			if err := validateEtcdClusterSpecLegacy(x, fieldEtcdClusters.Index(i)); err != nil {
				return err
			}
		}
		if err := validateEtcdTLS(c.Spec.EtcdClusters, fieldEtcdClusters); err != nil {
			return err
		}
		if err := validateEtcdStorage(c.Spec.EtcdClusters, fieldEtcdClusters); err != nil {
			return err
		}
	}

	if kubernetesRelease.GTE(semver.MustParse("1.4.0")) {
		if c.Spec.Networking != nil && c.Spec.Networking.Classic != nil {
			return field.Invalid(fieldSpec.Child("Networking"), "classic", "classic networking is not supported with kubernetes versions 1.4 and later")
		}
	}

	if c.Spec.Networking != nil && (c.Spec.Networking.AmazonVPC != nil || c.Spec.Networking.LyftVPC != nil) &&
		c.Spec.CloudProvider != "aws" {
		return field.Invalid(fieldSpec.Child("Networking"), "amazon-vpc-routed-eni", "amazon-vpc-routed-eni networking is supported only in AWS")
	}

	if kubernetesRelease.LT(semver.MustParse("1.7.0")) {
		if c.Spec.Networking != nil && c.Spec.Networking.Romana != nil {
			return field.Invalid(fieldSpec.Child("Networking"), "romana", "romana networking is not supported with kubernetes versions 1.6 or lower")
		}

		if c.Spec.Networking != nil && c.Spec.Networking.AmazonVPC != nil {
			return field.Invalid(fieldSpec.Child("Networking"), "amazon-vpc-routed-eni", "amazon-vpc-routed-eni networking is not supported with kubernetes versions 1.6 or lower")
		}

		if c.Spec.Networking != nil && c.Spec.Networking.LyftVPC != nil {
			return field.Invalid(fieldSpec.Child("Networking"), "cni-ipvlan-vpc-k8s", "cni-ipvlan-vpc-k8s networking is not supported with kubernetes versions 1.6 or lower")
		}
	}

	// Cilium specific validation rules
	if err := validateCilium(c); err != nil {
		return err
	}

	if errs := newValidateCluster(c); len(errs) != 0 {
		return errs[0]
	}

	return nil
}
753344
func (o *DeleteServiceIDParams) WithTimeout(timeout time.Duration) *DeleteServiceIDParams {
	o.SetTimeout(timeout)
	return o
}
1352721
func (s *NoopClient) TimingDuration(stat string, delta time.Duration, rate float32) error {
	return nil
}
1089629
func (o *GetIDParams) WithTimeout(timeout time.Duration) *GetIDParams {
	o.SetTimeout(timeout)
	return o
}