Skip to content

Commit 37e70ed

Browse files
Merge pull request #8 from sttts/sttts-is-valid
Add Name.IsValid
2 parents 322569f + 0065230 commit 37e70ed

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

name.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package logicalcluster
1919
import (
2020
"encoding/json"
2121
"path"
22+
"regexp"
2223
"strings"
2324
)
2425

@@ -47,6 +48,13 @@ func New(value string) Name {
4748
return Name{value}
4849
}
4950

51+
// NewValidated returns a Name from a string and whether it is a valid logical cluster.
52+
// A valid logical cluster returns true on IsValid().
53+
func NewValidated(value string) (Name, bool) {
54+
n := Name{value}
55+
return n, n.IsValid()
56+
}
57+
5058
// Empty returns true if the logical cluster value is unset.
5159
func (n Name) Empty() bool {
5260
return n.value == ""
@@ -121,3 +129,11 @@ func (n *Name) UnmarshalJSON(data []byte) error {
121129
func (n Name) HasPrefix(other Name) bool {
122130
return strings.HasPrefix(n.value, other.value)
123131
}
132+
133+
var lclusterRegExp = regexp.MustCompile(`^[a-z][a-z0-9-]*[a-z0-9](:[a-z][a-z0-9-]*[a-z0-9])*$`)
134+
135+
// IsValid returns true if the name is a Wildcard or a colon separated list of words where each word
136+
// starts with a lower-case letter and contains only lower-case letters, digits and hyphens.
137+
func (n Name) IsValid() bool {
138+
return n == Wildcard || lclusterRegExp.MatchString(n.value)
139+
}

name_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,45 @@ func TestJSON(t *testing.T) {
6868
require.NoError(t, err)
6969
require.Equal(t, jwt, jwt2)
7070
}
71+
72+
func TestIsValidCluster(t *testing.T) {
73+
tests := []struct {
74+
name string
75+
valid bool
76+
}{
77+
{"", false},
78+
{"*", true},
79+
80+
{"elephant", true},
81+
{"elephant:foo", true},
82+
{"elephant:foo:bar", true},
83+
84+
{"system", true},
85+
{"system:foo", true},
86+
{"system:foo:bar", true},
87+
88+
// the plugin does not decide about segment length, the server does
89+
{"elephant:b1234567890123456789012345678912", true},
90+
{"elephant:test-8827a131-f796-4473-8904-a0fa527696eb:b1234567890123456789012345678912", true},
91+
{"elephant:test-too-long-org-0020-4473-0030-a0fa-0040-5276-0050-sdg2-0060:b1234567890123456789012345678912", true},
92+
93+
{"elephant:", false},
94+
{":elephant", false},
95+
{"elephant::foo", false},
96+
{"elephant:föö:bär", false},
97+
{"elephant:bar_bar", false},
98+
{"elephant:a", false},
99+
{"elephant:0a", false},
100+
{"elephant:0bar", false},
101+
{"elephant/bar", false},
102+
{"elephant:bar-", false},
103+
{"elephant:-bar", false},
104+
}
105+
for _, tt := range tests {
106+
t.Run(tt.name, func(t *testing.T) {
107+
if got := New(tt.name).IsValid(); got != tt.valid {
108+
t.Errorf("isValid(%q) = %v, want %v", tt.name, got, tt.valid)
109+
}
110+
})
111+
}
112+
}

0 commit comments

Comments
 (0)