Skip to content

Commit 1949fc3

Browse files
committed
Ensure BMH name is a valid DNS hostname
Signed-off-by: Didrik Frimann Barroso Koren <[email protected]>
1 parent 1070d84 commit 1949fc3

File tree

2 files changed

+70
-11
lines changed

2 files changed

+70
-11
lines changed

internal/webhooks/metal3.io/v1alpha1/baremetalhost_validation.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"fmt"
2121
"net"
2222
"net/url"
23-
"regexp"
2423
"slices"
2524
"strings"
2625

@@ -30,6 +29,7 @@ import (
3029
corev1 "k8s.io/api/core/v1"
3130
k8serrors "k8s.io/apimachinery/pkg/api/errors"
3231
"k8s.io/apimachinery/pkg/runtime/schema"
32+
k8svalidation "k8s.io/apimachinery/pkg/util/validation"
3333
)
3434

3535
var (
@@ -61,7 +61,7 @@ func (webhook *BareMetalHost) validateHost(host *metal3api.BareMetalHost) []erro
6161
errs = append(errs, validateBMCAccess(host.Spec, bmcAccess)...)
6262

6363
if err := validateBMHName(host.Name); err != nil {
64-
errs = append(errs, err)
64+
errs = append(errs, err...)
6565
}
6666

6767
if err := validateDNSName(host.Spec.BMC.Address); err != nil {
@@ -183,18 +183,20 @@ func validateRAID(r *metal3api.RAIDConfig) []error {
183183
return errs
184184
}
185185

186-
func validateBMHName(bmhname string) error {
187-
invalidname, _ := regexp.MatchString(`[^A-Za-z0-9\.\-\_]`, bmhname)
188-
if invalidname {
189-
return errors.New("BareMetalHost resource name cannot contain characters other than [A-Za-z0-9._-]")
190-
}
191-
186+
func validateBMHName(bmhname string) []error {
187+
errorStrings := k8svalidation.IsDNS1123Label(bmhname)
192188
_, err := uuid.Parse(bmhname)
189+
190+
errs := make([]error, 0, len(errorStrings)+1)
191+
193192
if err == nil {
194-
return errors.New("BareMetalHost resource name cannot be a UUID")
193+
errs = []error{errors.New("BareMetalHost resource name cannot be a UUID")}
194+
}
195+
for i := range errorStrings {
196+
errs = append(errs, errors.New(errorStrings[i]))
195197
}
196198

197-
return nil
199+
return errs
198200
}
199201

200202
func validateDNSName(hostaddress string) error {

internal/webhooks/metal3.io/v1alpha1/baremetalhost_validation_test.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ func TestValidateCreate(t *testing.T) {
5050
Namespace: "test-namespace",
5151
}
5252

53+
om2 := metav1.ObjectMeta{
54+
Name: "test-name",
55+
Namespace: "test-namespace",
56+
}
57+
5358
inom := metav1.ObjectMeta{
5459
Name: "test~",
5560
Namespace: "test-namespace",
@@ -60,6 +65,26 @@ func TestValidateCreate(t *testing.T) {
6065
Namespace: "test-namespace",
6166
}
6267

68+
inom3 := metav1.ObjectMeta{
69+
Name: "-test",
70+
Namespace: "test-namespace",
71+
}
72+
73+
inom4 := metav1.ObjectMeta{
74+
Name: "test-",
75+
Namespace: "test-namespace",
76+
}
77+
78+
inom5 := metav1.ObjectMeta{
79+
Name: "CapitalizedTest",
80+
Namespace: "test-namespace",
81+
}
82+
83+
inom6 := metav1.ObjectMeta{
84+
Name: "verylongnamewhichshouldreachjustpastthelengthlimitof63characters",
85+
Namespace: "test-namespace",
86+
}
87+
6388
enable := true
6489

6590
// for RAID validation test cases
@@ -77,6 +102,12 @@ func TestValidateCreate(t *testing.T) {
77102
oldBMH: nil,
78103
wantedErr: "",
79104
},
105+
{
106+
name: "valid2",
107+
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: om2, Spec: metal3api.BareMetalHostSpec{}},
108+
oldBMH: nil,
109+
wantedErr: "",
110+
},
80111
{
81112
name: "validExternallyProvisioned",
82113
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: om, Spec: metal3api.BareMetalHostSpec{ExternallyProvisioned: true}},
@@ -86,14 +117,38 @@ func TestValidateCreate(t *testing.T) {
86117
name: "invalidName",
87118
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom, Spec: metal3api.BareMetalHostSpec{}},
88119
oldBMH: nil,
89-
wantedErr: "BareMetalHost resource name cannot contain characters other than [A-Za-z0-9._-]",
120+
wantedErr: "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')",
90121
},
91122
{
92123
name: "invalidName2",
93124
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom2, Spec: metal3api.BareMetalHostSpec{}},
94125
oldBMH: nil,
95126
wantedErr: "BareMetalHost resource name cannot be a UUID",
96127
},
128+
{
129+
name: "invalidName3LeadingHyphen",
130+
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom3, Spec: metal3api.BareMetalHostSpec{}},
131+
oldBMH: nil,
132+
wantedErr: "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')",
133+
},
134+
{
135+
name: "invalidName4TrailingHyphen",
136+
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom4, Spec: metal3api.BareMetalHostSpec{}},
137+
oldBMH: nil,
138+
wantedErr: "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')",
139+
},
140+
{
141+
name: "invalidName5CapitalChars",
142+
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom5, Spec: metal3api.BareMetalHostSpec{}},
143+
oldBMH: nil,
144+
wantedErr: "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')",
145+
},
146+
{
147+
name: "invalidName6LengthLimitOf63",
148+
newBMH: &metal3api.BareMetalHost{TypeMeta: tm, ObjectMeta: inom6, Spec: metal3api.BareMetalHostSpec{}},
149+
oldBMH: nil,
150+
wantedErr: "must be no more than 63 characters",
151+
},
97152
{
98153
name: "invalidRAID",
99154
newBMH: &metal3api.BareMetalHost{
@@ -863,6 +918,8 @@ func TestValidateCreate(t *testing.T) {
863918
{
864919
name: "disablePowerOff",
865920
newBMH: &metal3api.BareMetalHost{
921+
TypeMeta: tm,
922+
ObjectMeta: om,
866923
Spec: metal3api.BareMetalHostSpec{
867924
DisablePowerOff: true,
868925
Online: true,

0 commit comments

Comments
 (0)