diff --git a/cli/port.go b/cli/port.go index f23ac3be..00f714c5 100644 --- a/cli/port.go +++ b/cli/port.go @@ -3,7 +3,6 @@ package run import ( "fmt" "log" - "regexp" "strings" "github.com/docker/go-connections/nat" @@ -73,11 +72,18 @@ func CreatePublishedPorts(specs []string) (*PublishedPorts, error) { // validatePortSpecs matches the provided port specs against a set of rules to enable early exit if something is wrong func validatePortSpecs(specs []string) error { - // regex matching (no sophisticated IP matching at the moment) - regex := regexp.MustCompile(`^(((?P[\d\.]+)?:)?((?P[0-9]{0,6}):)?(?P[0-9]{1,6}))((/(?Pudp|tcp))?(?P(@(?P[\w-]+))+))$`) for _, spec := range specs { - if !regex.MatchString(spec) { - return fmt.Errorf("[ERROR] Provided port spec [%s] didn't match format specification (`[ip:][host-port:]container-port[/protocol]@node-specifier`)", spec) + atSplit := strings.Split(spec, "@") + _, err := nat.ParsePortSpec(atSplit[0]) + if err != nil { + return fmt.Errorf("ERROR: Invalid port specification [%s] in port mapping [%s]\n%+v", atSplit[0], spec, err) + } + if len(atSplit) > 0 { + for i := 1; i < len(atSplit); i++ { + if err := ValidateHostname(atSplit[i]); err != nil { + return fmt.Errorf("ERROR: Invalid node-specifier [%s] in port mapping [%s]\n%+v", atSplit[i], spec, err) + } + } } } return nil diff --git a/cli/util.go b/cli/util.go index 1688c57b..7a235e73 100644 --- a/cli/util.go +++ b/cli/util.go @@ -47,11 +47,15 @@ const clusterNameMaxSize int = 35 // within the 64 characters limit. func CheckClusterName(name string) error { if len(name) > clusterNameMaxSize { - return fmt.Errorf("[ERROR] Cluster name is too long") + return fmt.Errorf("[ERROR] Cluster name is too long (%d > %d)", len(name), clusterNameMaxSize) } + return fmt.Errorf("[ERROR] Invalid cluster name\n%+v", ValidateHostname(name)) +} +// ValidateHostname ensures that a cluster name is also a valid host name according to RFC 1123. +func ValidateHostname(name string) error { if name[0] == '-' || name[len(name)-1] == '-' { - return fmt.Errorf("[ERROR] Cluster name can not start or end with - (dash)") + return fmt.Errorf("[ERROR] Hostname [%s] must not start or end with - (dash)", name) } for _, c := range name { @@ -62,7 +66,7 @@ func CheckClusterName(name string) error { case c == '-': break default: - return fmt.Errorf("[ERROR] Cluster name contains characters other than 'Aa-Zz', '0-9' or '-'") + return fmt.Errorf("[ERROR] Hostname [%s] contains characters other than 'Aa-Zz', '0-9' or '-'", name) } }