Change:
Right now it is possible to add a cluster for which it won't be possible to create a client. For example client-related code does: while validation checks only: cc:
switching this to 1.6 as it's too late for 1.5. ok? (please switch it right back if you disagree)
Not a release blocker for 1.7.
are you interested in fixing this?
of course, will do that.
[MILESTONENOTIFIER] Milestone Removed Important: This issue was missing labels required for the v1.8 milestone for more than 7 days: kind: Must specify exactly one of [, , ]. priority: Must specify exactly one of [, , ]. Removing it from the milestone. <detailsAdditional instructions available <a href=""here</aThe commands available for adding these labels are documented <a href=""here</a</details

Discussion:
"//federation/apis/federation:go_default_library", "//pkg/api:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", <ins> "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", </ins> ], )

package validation import ( <ins> "fmt" "net" </ins> "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/federation/apis/federation" "k8s.io/kubernetes/pkg/api/validation"

// address is required. if len(spec.ServerAddressByClientCIDRs) == 0 { allErrs = append(allErrs, field.Required(fieldPath.Child("serverAddressByClientCIDRs"), "")) <ins> } else { for i, address := range spec.ServerAddressByClientCIDRs { idxPath := fieldPath.Child("serverAddressByClientCIDRs").Index(i) if len(address.ClientCIDR) > 0 { if _, _, err := net.ParseCIDR(address.ClientCIDR); err != nil { allErrs = append(allErrs, field.Invalid(idxPath.Child("clientCIDR"), address.ClientCIDR, fmt.Sprintf("must be a valid CIDR: %v", err))) } } } </ins> } return allErrs }

"testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" <ins> "k8s.io/apimachinery/pkg/util/validation/field" </ins> "k8s.io/kubernetes/federation/apis/federation" "k8s.io/kubernetes/pkg/api" ) <ins> func TestValidateClusterSpec(t *testing.T) { type validateClusterSpecTest struct { testName string spec     *federation.ClusterSpec path     *field.Path } successCases := []validateClusterSpecTest{ { testName: "normal CIDR", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "0.0.0.0/0", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, { testName: "missing CIDR", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, { testName: "no host in CIDR", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "0.0.0.0/32", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, } for _, successCase := range successCases { errs := ValidateClusterSpec(successCase.spec, successCase.path) if len(errs) != 0 { t.Errorf("expect success for testname: %q  but got: %v", successCase.testName, errs) } } errorCases := []validateClusterSpecTest{ { testName: "invalid CIDR : network missing", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "0.0.0.0", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, { testName: "invalid CIDR : invalid address value", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "256.0.0.0/16", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, { testName: "invalid CIDR : invalid address formation", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "0.0.0/16", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, { testName: "invalid CIDR : invalid network num", spec: &federation.ClusterSpec{ ServerAddressByClientCIDRs: []federation.ServerAddressByClientCIDR{ { ClientCIDR:    "0.0.0.0/33", ServerAddress: "localhost:8888", }, }, }, path: field.NewPath("spec"), }, } for _, errorCase := range errorCases { errs := ValidateClusterSpec(errorCase.spec, errorCase.path) if len(errs) == 0 { t.Errorf("expect failure for testname : %q", errorCase.testName) } } } </ins> func TestValidateCluster(t *testing.T) { successCases := []federation.Cluster{ {