Make sure we validate simple syntax on service commands
| ... | ... |
@@ -10,7 +10,6 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/api/types/swarm" |
| 11 | 11 |
"github.com/docker/docker/opts" |
| 12 | 12 |
runconfigopts "github.com/docker/docker/runconfig/opts" |
| 13 |
- "github.com/docker/go-connections/nat" |
|
| 14 | 13 |
"github.com/spf13/cobra" |
| 15 | 14 |
) |
| 16 | 15 |
|
| ... | ... |
@@ -244,17 +243,6 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error |
| 244 | 244 |
return healthConfig, nil |
| 245 | 245 |
} |
| 246 | 246 |
|
| 247 |
-// ValidatePort validates a string is in the expected format for a port definition |
|
| 248 |
-func ValidatePort(value string) (string, error) {
|
|
| 249 |
- portMappings, err := nat.ParsePortSpec(value) |
|
| 250 |
- for _, portMapping := range portMappings {
|
|
| 251 |
- if portMapping.Binding.HostIP != "" {
|
|
| 252 |
- return "", fmt.Errorf("HostIP is not supported by a service.")
|
|
| 253 |
- } |
|
| 254 |
- } |
|
| 255 |
- return value, err |
|
| 256 |
-} |
|
| 257 |
- |
|
| 258 | 247 |
// convertExtraHostsToSwarmHosts converts an array of extra hosts in cli |
| 259 | 248 |
// <host>:<ip> |
| 260 | 249 |
// into a swarmkit host format: |
| ... | ... |
@@ -663,24 +663,6 @@ func portConfigToString(portConfig *swarm.PortConfig) string {
|
| 663 | 663 |
return fmt.Sprintf("%v:%v/%s/%s", portConfig.PublishedPort, portConfig.TargetPort, protocol, mode)
|
| 664 | 664 |
} |
| 665 | 665 |
|
| 666 |
-// FIXME(vdemeester) port to opts.PortOpt |
|
| 667 |
-// This validation is only used for `--publish-rm`. |
|
| 668 |
-// The `--publish-rm` takes: |
|
| 669 |
-// <TargetPort>[/<Protocol>] (e.g., 80, 80/tcp, 53/udp) |
|
| 670 |
-func validatePublishRemove(val string) (string, error) {
|
|
| 671 |
- proto, port := nat.SplitProtoPort(val) |
|
| 672 |
- if proto != "tcp" && proto != "udp" {
|
|
| 673 |
- return "", fmt.Errorf("invalid protocol '%s' for %s", proto, val)
|
|
| 674 |
- } |
|
| 675 |
- if strings.Contains(port, ":") {
|
|
| 676 |
- return "", fmt.Errorf("invalid port format: '%s', should be <TargetPort>[/<Protocol>] (e.g., 80, 80/tcp, 53/udp)", port)
|
|
| 677 |
- } |
|
| 678 |
- if _, err := nat.ParsePort(port); err != nil {
|
|
| 679 |
- return "", err |
|
| 680 |
- } |
|
| 681 |
- return val, nil |
|
| 682 |
-} |
|
| 683 |
- |
|
| 684 | 666 |
func updatePorts(flags *pflag.FlagSet, portConfig *[]swarm.PortConfig) error {
|
| 685 | 667 |
// The key of the map is `port/protocol`, e.g., `80/tcp` |
| 686 | 668 |
portSet := map[string]swarm.PortConfig{}
|
| ... | ... |
@@ -362,29 +362,6 @@ func TestUpdatePortsRmWithProtocol(t *testing.T) {
|
| 362 | 362 |
assert.Equal(t, portConfigs[1].TargetPort, uint32(82)) |
| 363 | 363 |
} |
| 364 | 364 |
|
| 365 |
-// FIXME(vdemeester) port to opts.PortOpt |
|
| 366 |
-func TestValidatePort(t *testing.T) {
|
|
| 367 |
- validPorts := []string{"80/tcp", "80", "80/udp"}
|
|
| 368 |
- invalidPorts := map[string]string{
|
|
| 369 |
- "9999999": "out of range", |
|
| 370 |
- "80:80/tcp": "invalid port format", |
|
| 371 |
- "53:53/udp": "invalid port format", |
|
| 372 |
- "80:80": "invalid port format", |
|
| 373 |
- "80/xyz": "invalid protocol", |
|
| 374 |
- "tcp": "invalid syntax", |
|
| 375 |
- "udp": "invalid syntax", |
|
| 376 |
- "": "invalid protocol", |
|
| 377 |
- } |
|
| 378 |
- for _, port := range validPorts {
|
|
| 379 |
- _, err := validatePublishRemove(port) |
|
| 380 |
- assert.Equal(t, err, nil) |
|
| 381 |
- } |
|
| 382 |
- for port, e := range invalidPorts {
|
|
| 383 |
- _, err := validatePublishRemove(port) |
|
| 384 |
- assert.Error(t, err, e) |
|
| 385 |
- } |
|
| 386 |
-} |
|
| 387 |
- |
|
| 388 | 365 |
type secretAPIClientMock struct {
|
| 389 | 366 |
listResult []swarm.Secret |
| 390 | 367 |
} |
| ... | ... |
@@ -94,11 +94,20 @@ func (p *PortOpt) Set(value string) error {
|
| 94 | 94 |
} else {
|
| 95 | 95 |
// short syntax |
| 96 | 96 |
portConfigs := []swarm.PortConfig{}
|
| 97 |
- // We can ignore errors because the format was already validated by ValidatePort |
|
| 98 |
- ports, portBindings, _ := nat.ParsePortSpecs([]string{value})
|
|
| 97 |
+ ports, portBindingMap, err := nat.ParsePortSpecs([]string{value})
|
|
| 98 |
+ if err != nil {
|
|
| 99 |
+ return err |
|
| 100 |
+ } |
|
| 101 |
+ for _, portBindings := range portBindingMap {
|
|
| 102 |
+ for _, portBinding := range portBindings {
|
|
| 103 |
+ if portBinding.HostIP != "" {
|
|
| 104 |
+ return fmt.Errorf("HostIP is not supported.")
|
|
| 105 |
+ } |
|
| 106 |
+ } |
|
| 107 |
+ } |
|
| 99 | 108 |
|
| 100 | 109 |
for port := range ports {
|
| 101 |
- portConfig, err := ConvertPortToPortConfig(port, portBindings) |
|
| 110 |
+ portConfig, err := ConvertPortToPortConfig(port, portBindingMap) |
|
| 102 | 111 |
if err != nil {
|
| 103 | 112 |
return err |
| 104 | 113 |
} |
| ... | ... |
@@ -245,6 +245,42 @@ func TestPortOptInvalidComplexSyntax(t *testing.T) {
|
| 245 | 245 |
} |
| 246 | 246 |
} |
| 247 | 247 |
|
| 248 |
+func TestPortOptInvalidSimpleSyntax(t *testing.T) {
|
|
| 249 |
+ testCases := []struct {
|
|
| 250 |
+ value string |
|
| 251 |
+ expectedError string |
|
| 252 |
+ }{
|
|
| 253 |
+ {
|
|
| 254 |
+ value: "9999999", |
|
| 255 |
+ expectedError: "Invalid containerPort: 9999999", |
|
| 256 |
+ }, |
|
| 257 |
+ {
|
|
| 258 |
+ value: "80/xyz", |
|
| 259 |
+ expectedError: "Invalid proto: xyz", |
|
| 260 |
+ }, |
|
| 261 |
+ {
|
|
| 262 |
+ value: "tcp", |
|
| 263 |
+ expectedError: "Invalid containerPort: tcp", |
|
| 264 |
+ }, |
|
| 265 |
+ {
|
|
| 266 |
+ value: "udp", |
|
| 267 |
+ expectedError: "Invalid containerPort: udp", |
|
| 268 |
+ }, |
|
| 269 |
+ {
|
|
| 270 |
+ value: "", |
|
| 271 |
+ expectedError: "No port specified", |
|
| 272 |
+ }, |
|
| 273 |
+ {
|
|
| 274 |
+ value: "1.1.1.1:80:80", |
|
| 275 |
+ expectedError: "HostIP is not supported", |
|
| 276 |
+ }, |
|
| 277 |
+ } |
|
| 278 |
+ for _, tc := range testCases {
|
|
| 279 |
+ var port PortOpt |
|
| 280 |
+ assert.Error(t, port.Set(tc.value), tc.expectedError) |
|
| 281 |
+ } |
|
| 282 |
+} |
|
| 283 |
+ |
|
| 248 | 284 |
func assertContains(t *testing.T, portConfigs []swarm.PortConfig, expected swarm.PortConfig) {
|
| 249 | 285 |
var contains = false |
| 250 | 286 |
for _, portConfig := range portConfigs {
|