Skip to content

Commit

Permalink
Fix defaulting of legacy ClusterNetwork fields
Browse files Browse the repository at this point in the history
  • Loading branch information
danwinship committed Oct 16, 2017
1 parent dea5d49 commit 07049d4
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 44 deletions.
50 changes: 35 additions & 15 deletions pkg/network/apis/network/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,49 @@ func ValidateClusterNetwork(clusterNet *networkapi.ClusterNetwork) field.ErrorLi
allErrs := validation.ValidateObjectMeta(&clusterNet.ObjectMeta, false, path.ValidatePathSegmentName, field.NewPath("metadata"))
var testedCIDRS []*net.IPNet

// This check is mainly for ensuring backward compatibility
if len(clusterNet.Network) != 0 || clusterNet.HostSubnetLength != 0 {
//In the case that a user manually makes a clusterNetwork object with clusterNet.Network and clusterNet.HostubnetLength at least make sure they are valid values
clusterIPNet, err := validateCIDRv4(clusterNet.Network)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("network"), clusterNet.Network, err.Error()))
serviceIPNet, err := validateCIDRv4(clusterNet.ServiceNetwork)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("serviceNetwork"), clusterNet.ServiceNetwork, err.Error()))
}

if len(clusterNet.ClusterNetworks) == 0 {
// legacy ClusterNetwork; old fields must be set
if clusterNet.Network == "" {
allErrs = append(allErrs, field.Required(field.NewPath("network"), "network must be set (if clusterNetworks is empty)"))
} else if clusterNet.HostSubnetLength == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("hostsubnetlength"), "hostsubnetlength must be set (if clusterNetworks is empty)"))
} else {
clusterIPNet, err := validateCIDRv4(clusterNet.Network)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("network"), clusterNet.Network, err.Error()))
}
maskLen, addrLen := clusterIPNet.Mask.Size()
if clusterNet.HostSubnetLength > uint32(addrLen-maskLen) {
allErrs = append(allErrs, field.Invalid(field.NewPath("hostsubnetlength"), clusterNet.HostSubnetLength, "subnet length is too large for clusterNetwork"))
allErrs = append(allErrs, field.Invalid(field.NewPath("hostsubnetlength"), clusterNet.HostSubnetLength, "subnet length is too large for cidr"))
} else if clusterNet.HostSubnetLength < 2 {
allErrs = append(allErrs, field.Invalid(field.NewPath("hostsubnetlength"), clusterNet.HostSubnetLength, "subnet length must be at least 2"))
}

if (clusterIPNet != nil) && (serviceIPNet != nil) && configapi.CIDRsOverlap(clusterIPNet.String(), serviceIPNet.String()) {
allErrs = append(allErrs, field.Invalid(field.NewPath("serviceNetwork"), clusterNet.ServiceNetwork, "service network overlaps with cluster network"))
}
}
} else {
// "new" ClusterNetwork
if clusterNet.Name == networkapi.ClusterNetworkDefault {
if clusterNet.Network != clusterNet.ClusterNetworks[0].CIDR {
allErrs = append(allErrs, field.Invalid(field.NewPath("network"), clusterNet.Network, "network must be identical to clusterNetworks[0].cidr"))
}
if clusterNet.HostSubnetLength != clusterNet.ClusterNetworks[0].HostSubnetLength {
allErrs = append(allErrs, field.Invalid(field.NewPath("hostsubnetlength"), clusterNet.HostSubnetLength, "hostsubnetlength must be identical to clusterNetworks[0].hostSubnetLength"))
}
} else if clusterNet.Network != "" || clusterNet.HostSubnetLength != 0 {
if clusterNet.Network != clusterNet.ClusterNetworks[0].CIDR || clusterNet.HostSubnetLength != clusterNet.ClusterNetworks[0].HostSubnetLength {
allErrs = append(allErrs, field.Invalid(field.NewPath("clusterNetworks").Index(0), clusterNet.ClusterNetworks[0], "network and hostsubnetlength must be unset or identical to clusterNetworks[0]"))
}
}
}

if len(clusterNet.ClusterNetworks) == 0 && len(clusterNet.Network) == 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("clusterNetworks"), clusterNet.ClusterNetworks, "must have at least one cluster network CIDR"))
}
serviceIPNet, err := validateCIDRv4(clusterNet.ServiceNetwork)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("serviceNetwork"), clusterNet.ServiceNetwork, err.Error()))
}
for i, cn := range clusterNet.ClusterNetworks {
clusterIPNet, err := validateCIDRv4(cn.CIDR)
if err != nil {
Expand Down Expand Up @@ -103,7 +123,7 @@ func ValidateClusterNetwork(clusterNet *networkapi.ClusterNetwork) field.ErrorLi
allErrs = append(allErrs, field.Invalid(field.NewPath("network"), clusterNet.Network, "cannot change the default ClusterNetwork record via API."))
}
if clusterNet.HostSubnetLength != defaultClusterNetwork.HostSubnetLength {
allErrs = append(allErrs, field.Invalid(field.NewPath("hostSubnetLength"), clusterNet.HostSubnetLength, "cannot change the default ClusterNetwork record via API."))
allErrs = append(allErrs, field.Invalid(field.NewPath("hostsubnetlength"), clusterNet.HostSubnetLength, "cannot change the default ClusterNetwork record via API."))
}
if !reflect.DeepEqual(clusterNet.ClusterNetworks, defaultClusterNetwork.ClusterNetworks) {
allErrs = append(allErrs, field.Invalid(field.NewPath("ClusterNetworks"), clusterNet.ClusterNetworks, "cannot change the default ClusterNetwork record via API"))
Expand Down
110 changes: 83 additions & 27 deletions pkg/network/apis/network/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestValidateClusterNetwork(t *testing.T) {
expectedErrors: 0,
},
{
name: "Good one old network and hostsubnetlength set ",
name: "Good one old network and hostsubnetlength set",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: "any"},
Network: "10.20.0.0/16",
Expand All @@ -37,7 +37,29 @@ func TestValidateClusterNetwork(t *testing.T) {
expectedErrors: 0,
},
{
name: "only old network set ",
name: "old network set incorrectly",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: "any"},
Network: "10.30.0.0/16",
HostSubnetLength: 8,
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
},
expectedErrors: 1,
},
{
name: "old hostsubnetlength set incorrectly",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: "any"},
Network: "10.20.0.0/16",
HostSubnetLength: 9,
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
},
expectedErrors: 1,
},
{
name: "only old network set",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: "any"},
Network: "10.20.0.0/16",
Expand All @@ -47,7 +69,7 @@ func TestValidateClusterNetwork(t *testing.T) {
expectedErrors: 1,
},
{
name: "only old hostsubnetlength set ",
name: "only old hostsubnetlength set",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: "any"},
HostSubnetLength: 8,
Expand Down Expand Up @@ -185,10 +207,12 @@ func TestValidateClusterNetwork(t *testing.T) {

func TestSetDefaultClusterNetwork(t *testing.T) {
defaultClusterNetwork := networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.20.0.0/16",
HostSubnetLength: 8,
}
SetDefaultClusterNetwork(defaultClusterNetwork)

Expand All @@ -205,52 +229,84 @@ func TestSetDefaultClusterNetwork(t *testing.T) {
{
name: "Wrong Network",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.30.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.30.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.30.0.0/16",
HostSubnetLength: 8,
},
expectedErrors: 1,
expectedErrors: 2,
},
{
name: "Additional Network",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}, {CIDR: "10.30.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}, {CIDR: "10.30.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.20.0.0/16",
HostSubnetLength: 8,
},
expectedErrors: 1,
},
{
name: "Wrong HostSubnetLength",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 9}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 9}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.20.0.0/16",
HostSubnetLength: 9,
},
expectedErrors: 1,
expectedErrors: 2,
},
{
name: "Wrong ServiceNetwork",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.20.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.20.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.20.0.0/16",
HostSubnetLength: 8,
},
expectedErrors: 1,
},
{
name: "Wrong PluginName",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-subnet",
Network: "10.20.0.0/16",
HostSubnetLength: 8,
},
expectedErrors: 1,
},
{
name: "Wrong legacy Network",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-multitenant",
Network: "10.30.0.0/16",
HostSubnetLength: 8,
},
expectedErrors: 2,
},
{
name: "Missing legacy fields",
cn: &networkapi.ClusterNetwork{
ObjectMeta: metav1.ObjectMeta{Name: networkapi.ClusterNetworkDefault},
ClusterNetworks: []networkapi.ClusterNetworkEntry{{CIDR: "10.20.0.0/16", HostSubnetLength: 8}},
ServiceNetwork: "172.30.0.0/16",
PluginName: "redhat/openshift-ovs-subnet",
PluginName: "redhat/openshift-ovs-multitenant",
},
expectedErrors: 1,
expectedErrors: 4,
},
}

Expand Down
11 changes: 9 additions & 2 deletions pkg/network/master/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ func Start(networkConfig osconfigapi.MasterNetworkConfig, networkClient networkc

var err error
var clusterNetworkEntries []networkapi.ClusterNetworkEntry
for _, cidr := range networkConfig.ClusterNetworks {
clusterNetworkEntries = append(clusterNetworkEntries, networkapi.ClusterNetworkEntry{CIDR: cidr.CIDR, HostSubnetLength: cidr.HostSubnetLength})
for _, entry := range networkConfig.ClusterNetworks {
clusterNetworkEntries = append(clusterNetworkEntries, networkapi.ClusterNetworkEntry{CIDR: entry.CIDR, HostSubnetLength: entry.HostSubnetLength})
}
master.networkInfo, err = common.ParseNetworkInfo(clusterNetworkEntries, networkConfig.ServiceNetworkCIDR)
if err != nil {
return err
}
if len(clusterNetworkEntries) == 0 {
panic("No ClusterNetworks set in networkConfig; should have been defaulted in if not configured")
}

configCN := &networkapi.ClusterNetwork{
TypeMeta: metav1.TypeMeta{Kind: "ClusterNetwork"},
Expand All @@ -70,6 +73,10 @@ func Start(networkConfig osconfigapi.MasterNetworkConfig, networkClient networkc
ClusterNetworks: clusterNetworkEntries,
ServiceNetwork: networkConfig.ServiceNetworkCIDR,
PluginName: networkConfig.NetworkPluginName,

// Need to set these for backward compat
Network: clusterNetworkEntries[0].CIDR,
HostSubnetLength: clusterNetworkEntries[0].HostSubnetLength,
}
osapivalidation.SetDefaultClusterNetwork(*configCN)

Expand Down

0 comments on commit 07049d4

Please sign in to comment.