feat(namespace): add check function for namespace

This commit is contained in:
Adrien Raffin-Caboisse 2022-02-23 11:07:24 +01:00
parent fe0b43eaaf
commit 45727dbb21
No known key found for this signature in database
GPG key ID: 7FB60532DEBEAD6A
2 changed files with 77 additions and 5 deletions

View file

@ -27,7 +27,7 @@ const (
labelHostnameLength = 63 labelHostnameLength = 63
) )
var normalizeNamespaceRegex = regexp.MustCompile("[^a-z0-9-.]+") var invalidCharsInNamespaceRegex = regexp.MustCompile("[^a-z0-9-.]+")
// Namespace is the way Headscale implements the concept of users in Tailscale // Namespace is the way Headscale implements the concept of users in Tailscale
// //
@ -281,7 +281,7 @@ func NormalizeNamespaceName(name string) (string, error) {
name = strings.ToLower(name) name = strings.ToLower(name)
name = strings.ReplaceAll(name, "@", ".") name = strings.ReplaceAll(name, "@", ".")
name = strings.ReplaceAll(name, "'", "") name = strings.ReplaceAll(name, "'", "")
name = normalizeNamespaceRegex.ReplaceAllString(name, "-") name = invalidCharsInNamespaceRegex.ReplaceAllString(name, "-")
for _, elt := range strings.Split(name, ".") { for _, elt := range strings.Split(name, ".") {
if len(elt) > labelHostnameLength { if len(elt) > labelHostnameLength {
@ -295,3 +295,29 @@ func NormalizeNamespaceName(name string) (string, error) {
return name, nil return name, nil
} }
func CheckNamespaceName(name string) error {
if len(name) > labelHostnameLength {
return fmt.Errorf(
"Namespace must not be over 63 chars. %v doesn't comply with this rule: %w",
name,
errInvalidNamespaceName,
)
}
if strings.ToLower(name) != name {
return fmt.Errorf(
"Namespace name should be lowercase. %v doesn't comply with this rule: %w",
name,
errInvalidNamespaceName,
)
}
if invalidCharsInNamespaceRegex.MatchString(name) {
return fmt.Errorf(
"Namespace name should only be composed of lowercase ASCII letters numbers, hyphen and dots. %v doesn't comply with theses rules: %w",
name,
errInvalidNamespaceName,
)
}
return nil
}

View file

@ -74,13 +74,13 @@ func (s *Suite) TestRenameNamespace(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(namespaces), check.Equals, 1) c.Assert(len(namespaces), check.Equals, 1)
err = app.RenameNamespace("test", "test_renamed") err = app.RenameNamespace("test", "test-renamed")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
_, err = app.GetNamespace("test") _, err = app.GetNamespace("test")
c.Assert(err, check.Equals, errNamespaceNotFound) c.Assert(err, check.Equals, errNamespaceNotFound)
_, err = app.GetNamespace("test_renamed") _, err = app.GetNamespace("test-renamed")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
err = app.RenameNamespace("test_does_not_exit", "test") err = app.RenameNamespace("test_does_not_exit", "test")
@ -90,7 +90,7 @@ func (s *Suite) TestRenameNamespace(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(namespaceTest2.Name, check.Equals, "test2") c.Assert(namespaceTest2.Name, check.Equals, "test2")
err = app.RenameNamespace("test2", "test_renamed") err = app.RenameNamespace("test2", "test-renamed")
c.Assert(err, check.Equals, errNamespaceExists) c.Assert(err, check.Equals, errNamespaceExists)
} }
@ -301,3 +301,49 @@ func TestNormalizeNamespaceName(t *testing.T) {
}) })
} }
} }
func TestCheckNamespaceName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "valid: namespace",
args: args{name: "valid-namespace"},
wantErr: false,
},
{
name: "invalid: capitalized namespace",
args: args{name: "Invalid-CapItaLIzed-namespace"},
wantErr: true,
},
{
name: "invalid: email as namespace",
args: args{name: "foo.bar@example.com"},
wantErr: true,
},
{
name: "invalid: chars in namespace name",
args: args{name: "super-namespace+name"},
wantErr: true,
},
{
name: "invalid: too long name for namespace",
args: args{
name: "super-long-namespace-name-that-should-be-a-little-more-than-63-chars",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := CheckNamespaceName(tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("CheckNamespaceName() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}