diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 2990291997..90c536a450 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -9,6 +9,7 @@ import ( dockerref "github.com/containers/image/docker/reference" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" @@ -79,6 +80,7 @@ func ValidateInstallConfig(c *types.InstallConfig) field.ErrorList { if c.Networking != nil { allErrs = append(allErrs, validateNetworking(c.Networking, field.NewPath("networking"))...) allErrs = append(allErrs, validateNetworkingIPVersion(c.Networking, &c.Platform)...) + allErrs = append(allErrs, validateNetworkingForPlatform(c.Networking, &c.Platform, field.NewPath("networking"))...) } else { allErrs = append(allErrs, field.Required(field.NewPath("networking"), "networking is required")) } @@ -279,6 +281,47 @@ func validateNetworking(n *types.Networking, fldPath *field.Path) field.ErrorLis return allErrs } +func validateNetworkingForPlatform(n *types.Networking, platform *types.Platform, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + switch { + case platform.Libvirt != nil: + errMsg := "overlaps with default Docker Bridge subnet" + for idx, mn := range n.MachineNetwork { + if validate.DoCIDRsOverlap(&mn.CIDR.IPNet, validate.DockerBridgeCIDR) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("machineNewtork").Index(idx), mn.CIDR.String(), errMsg)) + } + } + for idx, sn := range n.ServiceNetwork { + if validate.DoCIDRsOverlap(&sn.IPNet, validate.DockerBridgeCIDR) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceNetwork").Index(idx), sn.String(), errMsg)) + } + } + for idx, cn := range n.ClusterNetwork { + if validate.DoCIDRsOverlap(&cn.CIDR.IPNet, validate.DockerBridgeCIDR) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterNetwork").Index(idx), cn.CIDR.String(), errMsg)) + } + } + default: + warningMsgFmt := "%s: %s overlaps with default Docker Bridge subnet" + for idx, mn := range n.MachineNetwork { + if validate.DoCIDRsOverlap(&mn.CIDR.IPNet, validate.DockerBridgeCIDR) { + logrus.Warnf(warningMsgFmt, fldPath.Child("machineNetwork").Index(idx), mn.CIDR.String()) + } + } + for idx, sn := range n.ServiceNetwork { + if validate.DoCIDRsOverlap(&sn.IPNet, validate.DockerBridgeCIDR) { + logrus.Warnf(warningMsgFmt, fldPath.Child("serviceNetwork").Index(idx), sn.String()) + } + } + for idx, cn := range n.ClusterNetwork { + if validate.DoCIDRsOverlap(&cn.CIDR.IPNet, validate.DockerBridgeCIDR) { + logrus.Warnf(warningMsgFmt, fldPath.Child("clusterNetwork").Index(idx), cn.CIDR.String()) + } + } + } + return allErrs +} + func validateClusterNetwork(n *types.Networking, cn *types.ClusterNetworkEntry, idx int, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if err := validate.SubnetCIDR(&cn.CIDR.IPNet); err != nil { diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index d7456c2e37..98884a6f65 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -961,6 +961,25 @@ func TestValidateInstallConfig(t *testing.T) { }(), expectedError: `^credentialsMode: Unsupported value: "bad-mode": supported values: "manual", "mint", "passthrough"$`, }, + { + name: "allowed docker bridge with non-libvirt", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Networking.MachineNetwork = []types.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.17.64.0/18")}} + return c + }(), + expectedError: ``, + }, + { + name: "docker bridge not allowed with libvirt", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Platform = types.Platform{Libvirt: validLibvirtPlatform()} + c.Networking.MachineNetwork = []types.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.17.64.0/18")}} + return c + }(), + expectedError: `\Q[networking.machineNewtork[0]: Invalid value: "172.17.64.0/18": overlaps with default Docker Bridge subnet, platform: Invalid value: "libvirt": must specify one of the platforms (\E.*\Q)]\E`, + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/validate/validate.go b/pkg/validate/validate.go index 3766a86e35..b67c6456cf 100644 --- a/pkg/validate/validate.go +++ b/pkg/validate/validate.go @@ -19,7 +19,8 @@ import ( ) var ( - dockerBridgeCIDR = func() *net.IPNet { + // DockerBridgeCIDR is the network range that is used by default network for docker. + DockerBridgeCIDR = func() *net.IPNet { _, cidr, _ := net.ParseCIDR("172.17.0.0/16") return cidr }() @@ -134,9 +135,6 @@ func SubnetCIDR(cidr *net.IPNet) error { if nip.String() != cidr.IP.String() { return fmt.Errorf("invalid network address. got %s, expecting %s", cidr.String(), (&net.IPNet{IP: nip, Mask: cidr.Mask}).String()) } - if DoCIDRsOverlap(cidr, dockerBridgeCIDR) { - return fmt.Errorf("overlaps with default Docker Bridge subnet (%v)", cidr.String()) - } return nil } diff --git a/pkg/validate/validate_test.go b/pkg/validate/validate_test.go index 206020aa80..bdd3b74bbc 100644 --- a/pkg/validate/validate_test.go +++ b/pkg/validate/validate_test.go @@ -61,8 +61,6 @@ func TestSubnetCIDR(t *testing.T) { {"1.2.3.4/32", ""}, {"0:0:0:0:0:1:102:304/116", "invalid network address. got ::1:102:304/116, expecting ::1:102:0/116"}, {"0:0:0:0:0:ffff:102:304/116", "invalid network address. got 1.2.3.4/20, expecting 1.2.0.0/20"}, - {"172.17.0.0/20", "overlaps with default Docker Bridge subnet (172.17.0.0/20)"}, - {"172.0.0.0/8", "overlaps with default Docker Bridge subnet (172.0.0.0/8)"}, {"255.255.255.255/1", "invalid network address. got 255.255.255.255/1, expecting 128.0.0.0/1"}, {"255.255.255.255/32", ""}, }