From 9b54e88aed7356222c5c93072660e3ed96314b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20G=C3=BC=C3=A7l=C3=BC?= Date: Mon, 11 Oct 2021 10:38:20 +0300 Subject: [PATCH 1/3] Add validation to check APIVIP is IPv4 in dual-stack for Bare Metal This PR adds validation to check VIP for API belongs to IPv4 family for bare metal dual-stack. Because in dual-stack, primary network must be in IPv4. Hence, APIVIP must also be in IPv4. --- pkg/types/validation/installconfig.go | 6 ++++++ pkg/types/validation/installconfig_test.go | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index eff0cca665b..882c54c32ee 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -224,6 +224,12 @@ func validateNetworkingIPVersion(n *types.Networking, p *types.Platform) field.E case p.Azure != nil && experimentalDualStackEnabled: logrus.Warnf("Using experimental Azure dual-stack support") case p.BareMetal != nil: + // VIP for API should belong to IPv4 family in Bare Metal dual-stack + // Because primary network should also be IPv4. + apiVIP := net.ParseIP(p.BareMetal.APIVIP) + if apiVIP.To4() == nil { + allErrs = append(allErrs, field.Invalid(field.NewPath("networking", "baremetal", "apiVIP"), p.BareMetal.APIVIP, "VIP for the API must be in IPv4 network for dual-stack IPv4/IPv6")) + } case p.None != nil: default: allErrs = append(allErrs, field.Invalid(field.NewPath("networking"), "DualStack", "dual-stack IPv4/IPv6 is not supported for this platform, specify only one type of address")) diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index c2cfcc90254..bf833bded64 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -637,6 +637,19 @@ func TestValidateInstallConfig(t *testing.T) { }(), expectedError: `^platform\.baremetal\.apiVIP: Invalid value: "10\.1\.0\.5": IP expected to be in one of the machine networks: 10.0.0.0/16$`, }, + { + name: "baremetal API VIP set to an incorrect IP Family", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Networking = validDualStackNetworkingConfig() + c.Platform = types.Platform{ + BareMetal: validBareMetalPlatform(), + } + c.Platform.BareMetal.APIVIP = "ffd0::" + return c + }(), + expectedError: `networking.baremetal.apiVIP: Invalid value: "ffd0::": VIP for the API must be in IPv4 network for dual-stack IPv4/IPv6`, + }, { name: "baremetal Ingress VIP not an IP", installConfig: func() *types.InstallConfig { From edc15c4a4213205d9cdbc0aa3602ae0da37842ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20G=C3=BC=C3=A7l=C3=BC?= Date: Tue, 12 Oct 2021 10:39:32 +0300 Subject: [PATCH 2/3] Validate APIVIP IP family according Primary IP family --- pkg/types/validation/installconfig.go | 12 +++++++----- pkg/types/validation/installconfig_test.go | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 882c54c32ee..7a72a2da90b 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -224,11 +224,13 @@ func validateNetworkingIPVersion(n *types.Networking, p *types.Platform) field.E case p.Azure != nil && experimentalDualStackEnabled: logrus.Warnf("Using experimental Azure dual-stack support") case p.BareMetal != nil: - // VIP for API should belong to IPv4 family in Bare Metal dual-stack - // Because primary network should also be IPv4. - apiVIP := net.ParseIP(p.BareMetal.APIVIP) - if apiVIP.To4() == nil { - allErrs = append(allErrs, field.Invalid(field.NewPath("networking", "baremetal", "apiVIP"), p.BareMetal.APIVIP, "VIP for the API must be in IPv4 network for dual-stack IPv4/IPv6")) + apiVIPIPFamily := corev1.IPv6Protocol + if net.ParseIP(p.BareMetal.APIVIP).To4() != nil { + apiVIPIPFamily = corev1.IPv4Protocol + } + + if apiVIPIPFamily != presence["machineNetwork"].Primary { + allErrs = append(allErrs, field.Invalid(field.NewPath("networking", "baremetal", "apiVIP"), p.BareMetal.APIVIP, "VIP for the API must be of the same IP family with machine network's primary IP Family for dual-stack IPv4/IPv6")) } case p.None != nil: default: diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index bf833bded64..ca0ceab03a0 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -648,7 +648,7 @@ func TestValidateInstallConfig(t *testing.T) { c.Platform.BareMetal.APIVIP = "ffd0::" return c }(), - expectedError: `networking.baremetal.apiVIP: Invalid value: "ffd0::": VIP for the API must be in IPv4 network for dual-stack IPv4/IPv6`, + expectedError: `networking.baremetal.apiVIP: Invalid value: "ffd0::": VIP for the API must be of the same IP family with machine network's primary IP Family for dual-stack IPv4/IPv6`, }, { name: "baremetal Ingress VIP not an IP", From 32f0530d7d21bcc43f7211164af5d148dfb62a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arda=20G=C3=BC=C3=A7l=C3=BC?= Date: Wed, 13 Oct 2021 08:27:39 +0300 Subject: [PATCH 3/3] Add validation ingressVIP of same IP family with Machine Network --- pkg/types/validation/installconfig.go | 9 +++++++++ pkg/types/validation/installconfig_test.go | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 7a72a2da90b..aa2cb311bf1 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -232,6 +232,15 @@ func validateNetworkingIPVersion(n *types.Networking, p *types.Platform) field.E if apiVIPIPFamily != presence["machineNetwork"].Primary { allErrs = append(allErrs, field.Invalid(field.NewPath("networking", "baremetal", "apiVIP"), p.BareMetal.APIVIP, "VIP for the API must be of the same IP family with machine network's primary IP Family for dual-stack IPv4/IPv6")) } + + ingressVIPIPFamily := corev1.IPv6Protocol + if net.ParseIP(p.BareMetal.IngressVIP).To4() != nil { + ingressVIPIPFamily = corev1.IPv4Protocol + } + + if ingressVIPIPFamily != presence["machineNetwork"].Primary { + allErrs = append(allErrs, field.Invalid(field.NewPath("networking", "baremetal", "ingressVIP"), p.BareMetal.IngressVIP, "VIP for the Ingress must be of the same IP family with machine network's primary IP Family for dual-stack IPv4/IPv6")) + } case p.None != nil: default: allErrs = append(allErrs, field.Invalid(field.NewPath("networking"), "DualStack", "dual-stack IPv4/IPv6 is not supported for this platform, specify only one type of address")) diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index ca0ceab03a0..6bf50ea1624 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -662,6 +662,19 @@ func TestValidateInstallConfig(t *testing.T) { }(), expectedError: `^\[platform\.baremetal\.ingressVIP: Invalid value: "test": "test" is not a valid IP, platform\.baremetal\.ingressVIP: Invalid value: "test": IP expected to be in one of the machine networks: 10.0.0.0/16]$`, }, + { + name: "baremetal Ingress VIP set to an incorrect IP Family", + installConfig: func() *types.InstallConfig { + c := validInstallConfig() + c.Networking = validDualStackNetworkingConfig() + c.Platform = types.Platform{ + BareMetal: validBareMetalPlatform(), + } + c.Platform.BareMetal.IngressVIP = "ffd0::" + return c + }(), + expectedError: `networking.baremetal.ingressVIP: Invalid value: "ffd0::": VIP for the Ingress must be of the same IP family with machine network's primary IP Family for dual-stack IPv4/IPv6`, + }, { name: "baremetal Ingress VIP set to an incorrect value", installConfig: func() *types.InstallConfig {