diff --git a/libnetwork/config/config.go b/libnetwork/config/config.go index 171f1852c0..cece4ed45a 100644 --- a/libnetwork/config/config.go +++ b/libnetwork/config/config.go @@ -17,11 +17,11 @@ import ( "github.com/docker/libnetwork/osl" ) -// restrictedNameRegex represents the regular expression which regulates the allowed network or endpoint names. -const restrictedNameRegex = `^[\w]+[\w-. ]*[\w]+$` +// RestrictedNameChars collects the characters allowed to represent a network or endpoint name. +const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` // RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. -var restrictedNamePattern = regexp.MustCompile(restrictedNameRegex) +var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`) // Config encapsulates configurations of various Libnetwork components type Config struct { @@ -243,7 +243,7 @@ func (c *Config) ProcessOptions(options ...Option) { // ValidateName validates configuration objects supported by libnetwork func ValidateName(name string) error { if !restrictedNamePattern.MatchString(name) { - return fmt.Errorf("%q includes invalid characters, resource name has to conform to %q", name, restrictedNameRegex) + return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars) } return nil } diff --git a/libnetwork/config/config_test.go b/libnetwork/config/config_test.go index 72776f0e9e..a5feebac58 100644 --- a/libnetwork/config/config_test.go +++ b/libnetwork/config/config_test.go @@ -46,37 +46,17 @@ func TestOptionsLabels(t *testing.T) { } func TestValidName(t *testing.T) { - assertName(t, "test", true) - assertName(t, "test1", true) - assertName(t, "test1.2_3", true) - assertName(t, "_test", true) - assertName(t, "test_", true) - assertName(t, "looks-good", true) - assertName(t, " test", false) - assertName(t, "test ", false) - assertName(t, "test.", false) - assertName(t, ".test", false) - assertName(t, "", false) - assertName(t, " ", false) - assertName(t, "<>$$^", false) - assertName(t, "this is a good network name", true) - assertName(t, "this is also-good", true) - assertName(t, " this is a not good network name", false) - assertName(t, "this is a not either ", false) - assertName(t, "this one\nis not good", false) - assertName(t, "this one\tis not good", false) - assertName(t, "this one\ris not good", false) - assertName(t, "this one\vis not good", false) - assertName(t, "this one\fis not good", false) -} -func assertName(t *testing.T, name string, mustSucceed bool) { - msg := "Name validation succeeds for a case when it is expected to fail" - if mustSucceed { - msg = "Name validation fails for a name that must be accepted" + if err := ValidateName("test"); err != nil { + t.Fatal("Name validation fails for a name that must be accepted") } - err := ValidateName(name) - if (err == nil) != mustSucceed { - t.Fatalf("%s: %s", msg, name) + if err := ValidateName(""); err == nil { + t.Fatal("Name validation succeeds for a case when it is expected to fail") + } + if err := ValidateName(" "); err == nil { + t.Fatal("Name validation succeeds for a case when it is expected to fail") + } + if err := ValidateName("<>$$^"); err == nil { + t.Fatal("Name validation succeeds for a case when it is expected to fail") } }