Skip to content

Commit 7dafbe3

Browse files
authored
Merge pull request kubernetes#90391 from johscheuer/improve-error-message-svc-cidr
Improve the error message for the service cidr check
2 parents a3d532a + 4c5b46d commit 7dafbe3

File tree

2 files changed

+97
-9
lines changed

2 files changed

+97
-9
lines changed

cmd/kube-apiserver/app/options/validation.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535
// validateClusterIPFlags is expected to be called after Complete()
3636
func validateClusterIPFlags(options *ServerRunOptions) []error {
3737
var errs []error
38+
// maxCIDRBits is used to define the maximum CIDR size for the cluster ip(s)
39+
const maxCIDRBits = 20
3840

3941
// validate that primary has been processed by user provided values or it has been defaulted
4042
if options.PrimaryServiceClusterIPRange.IP == nil {
@@ -48,9 +50,8 @@ func validateClusterIPFlags(options *ServerRunOptions) []error {
4850

4951
// Complete() expected to have set Primary* and Secondary*
5052
// primary CIDR validation
51-
var ones, bits = options.PrimaryServiceClusterIPRange.Mask.Size()
52-
if bits-ones > 20 {
53-
errs = append(errs, errors.New("specified --service-cluster-ip-range is too large"))
53+
if err := validateMaxCIDRRange(options.PrimaryServiceClusterIPRange, maxCIDRBits, "--service-cluster-ip-range"); err != nil {
54+
errs = append(errs, err)
5455
}
5556

5657
// Secondary IP validation
@@ -74,18 +75,26 @@ func validateClusterIPFlags(options *ServerRunOptions) []error {
7475
errs = append(errs, errors.New("--service-cluster-ip-range and --secondary-service-cluster-ip-range must be of different IP family"))
7576
}
7677

77-
// Should be smallish sized cidr, this thing is kept in etcd
78-
// bigger cidr (specially those offered by IPv6) will add no value
79-
// significantly increase snapshotting time.
80-
var ones, bits = options.SecondaryServiceClusterIPRange.Mask.Size()
81-
if bits-ones > 20 {
82-
errs = append(errs, errors.New("specified --secondary-service-cluster-ip-range is too large"))
78+
if err := validateMaxCIDRRange(options.SecondaryServiceClusterIPRange, maxCIDRBits, "--secondary-service-cluster-ip-range"); err != nil {
79+
errs = append(errs, err)
8380
}
8481
}
8582

8683
return errs
8784
}
8885

86+
func validateMaxCIDRRange(cidr net.IPNet, maxCIDRBits int, cidrFlag string) error {
87+
// Should be smallish sized cidr, this thing is kept in etcd
88+
// bigger cidr (specially those offered by IPv6) will add no value
89+
// significantly increase snapshotting time.
90+
var ones, bits = cidr.Mask.Size()
91+
if bits-ones > maxCIDRBits {
92+
return fmt.Errorf("specified %s is too large; for %d-bit addresses, the mask must be >= %d", cidrFlag, bits, bits-maxCIDRBits)
93+
}
94+
95+
return nil
96+
}
97+
8998
func validateServiceNodePort(options *ServerRunOptions) []error {
9099
var errs []error
91100

cmd/kube-apiserver/app/options/validation_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ func TestClusterSerivceIPRange(t *testing.T) {
9595
options: makeOptionsWithCIDRs("10.0.0.0/16", "3000::/108"),
9696
enableDualStack: false,
9797
},
98+
{
99+
name: "service cidr to big",
100+
expectErrors: true,
101+
options: makeOptionsWithCIDRs("10.0.0.0/8", ""),
102+
enableDualStack: true,
103+
},
104+
{
105+
name: "dual-stack secondary cidr to big",
106+
expectErrors: true,
107+
options: makeOptionsWithCIDRs("10.0.0.0/16", "3000::/64"),
108+
enableDualStack: true,
109+
},
98110
/* success cases */
99111
{
100112
name: "valid primary",
@@ -130,3 +142,70 @@ func TestClusterSerivceIPRange(t *testing.T) {
130142
})
131143
}
132144
}
145+
146+
func getIPnetFromCIDR(cidr string) *net.IPNet {
147+
_, ipnet, _ := net.ParseCIDR(cidr)
148+
return ipnet
149+
}
150+
151+
func TestValidateMaxCIDRRange(t *testing.T) {
152+
testCases := []struct {
153+
// tc.cidr, tc.maxCIDRBits, tc.cidrFlag) tc.expectedErrorMessage
154+
name string
155+
cidr net.IPNet
156+
maxCIDRBits int
157+
cidrFlag string
158+
expectedErrorMessage string
159+
expectErrors bool
160+
}{
161+
{
162+
name: "valid ipv4 cidr",
163+
cidr: *getIPnetFromCIDR("10.92.0.0/12"),
164+
maxCIDRBits: 20,
165+
cidrFlag: "--service-cluster-ip-range",
166+
expectedErrorMessage: "",
167+
expectErrors: false,
168+
},
169+
{
170+
name: "valid ipv6 cidr",
171+
cidr: *getIPnetFromCIDR("3000::/108"),
172+
maxCIDRBits: 20,
173+
cidrFlag: "--service-cluster-ip-range",
174+
expectedErrorMessage: "",
175+
expectErrors: false,
176+
},
177+
{
178+
name: "ipv4 cidr to big",
179+
cidr: *getIPnetFromCIDR("10.92.0.0/8"),
180+
maxCIDRBits: 20,
181+
cidrFlag: "--service-cluster-ip-range",
182+
expectedErrorMessage: "specified --service-cluster-ip-range is too large; for 32-bit addresses, the mask must be >= 12",
183+
expectErrors: true,
184+
},
185+
{
186+
name: "ipv6 cidr to big",
187+
cidr: *getIPnetFromCIDR("3000::/64"),
188+
maxCIDRBits: 20,
189+
cidrFlag: "--service-cluster-ip-range",
190+
expectedErrorMessage: "specified --service-cluster-ip-range is too large; for 128-bit addresses, the mask must be >= 108",
191+
expectErrors: true,
192+
},
193+
}
194+
195+
for _, tc := range testCases {
196+
t.Run(tc.name, func(t *testing.T) {
197+
err := validateMaxCIDRRange(tc.cidr, tc.maxCIDRBits, tc.cidrFlag)
198+
if err != nil && !tc.expectErrors {
199+
t.Errorf("expected no errors, error found %+v", err)
200+
}
201+
202+
if err == nil && tc.expectErrors {
203+
t.Errorf("expected errors, no errors found")
204+
}
205+
206+
if err != nil && tc.expectErrors && err.Error() != tc.expectedErrorMessage {
207+
t.Errorf("Expected error message: \"%s\"\nGot: \"%s\"", tc.expectedErrorMessage, err.Error())
208+
}
209+
})
210+
}
211+
}

0 commit comments

Comments
 (0)