Skip to content

Commit

Permalink
add port indexer to be sure a service port declaration is unique
Browse files Browse the repository at this point in the history
Signed-off-by: Guillaume Lours <[email protected]>
  • Loading branch information
glours committed Jan 16, 2024
1 parent 00be3c8 commit 7668037
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
38 changes: 38 additions & 0 deletions override/uncity.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func init() {
unique["services.*.expose"] = exposeIndexer
unique["services.*.secrets"] = mountIndexer("/run/secrets")
unique["services.*.configs"] = mountIndexer("")
unique["services.*.ports"] = portIndexer
}

// EnforceUnicity removes redefinition of elements declared in a sequence
Expand Down Expand Up @@ -136,3 +137,40 @@ func mountIndexer(defaultPath string) indexer {
}
}
}

func portIndexer(y any, p tree.Path) (string, error) {
switch value := y.(type) {
case int:
return strconv.Itoa(value), nil
case map[string]any:
target, ok := value["target"].(int)
if !ok {
return "", fmt.Errorf("service ports %s is missing a target port", p)
}
published, ok := value["published"].(string)
if !ok {
// try to parse it as an int
if pub, ok := value["published"].(int); !ok {
return "", fmt.Errorf("service ports %s is missing a published port", p)
} else {

Check warning on line 155 in override/uncity.go

View workflow job for this annotation

GitHub Actions / test (1.21, ubuntu-latest)

indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive)

Check warning on line 155 in override/uncity.go

View workflow job for this annotation

GitHub Actions / test (1.20, ubuntu-latest)

indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive)
published = fmt.Sprintf("%d", pub)
}
}
host, ok := value["host_ip"].(string)
if !ok {
host = "0.0.0.0"
}
protocol, ok := value["protocol"].(string)
if !ok {
protocol = "tcp"
}
mode, ok := value["mode"].(string)
if !ok {
mode = "ingress"
}
return fmt.Sprintf("%s:%s:%d/%s/%s", host, published, target, protocol, mode), nil
case string:
return value, nil
}
return "", nil
}
68 changes: 68 additions & 0 deletions override/uncity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,74 @@ services:
`)
}

func Test_PortsShortUnicity(t *testing.T) {
assertUnicity(t, `
services:
test:
image: foo
ports:
- "9080:80"
- "9081:81"
- "9080:80"
- "5000"
- "6060:6060/udp"
- "9080:6060/udp"
`, `
services:
test:
image: foo
ports:
- "9080:80"
- "9081:81"
- "5000"
- "6060:6060/udp"
- "9080:6060/udp"
`)
}

func Test_PortsLongtUnicity(t *testing.T) {
assertUnicity(t, `
services:
test:
image: foo
ports:
- target: 80
host_ip: 127.0.0.1
published: "8080"
protocol: tcp
mode: host
- target: 81
published: "8080"
protocol: tcp
- target: 80
host_ip: 127.0.0.1
published: "8080"
protocol: tcp
mode: ingress
- target: 81
published: "8080"
protocol: tcp
`, `
services:
test:
image: foo
ports:
- target: 80
host_ip: 127.0.0.1
published: "8080"
protocol: tcp
mode: host
- target: 81
published: "8080"
protocol: tcp
- target: 80
host_ip: 127.0.0.1
published: "8080"
protocol: tcp
mode: ingress
`)
}

func assertUnicity(t *testing.T, before string, expected string) {
got, err := EnforceUnicity(unmarshall(t, before))
assert.NilError(t, err)
Expand Down

0 comments on commit 7668037

Please sign in to comment.