Merge pull request #30813 from yongtang/30232-service-ls-ports

Add `PORTS` field for `docker service ls` (`ingress`)
This commit is contained in:
Sebastiaan van Stijn 2017-04-04 17:04:27 +02:00 committed by GitHub
commit 9a5513b791
2 changed files with 92 additions and 11 deletions

View File

@ -1,6 +1,7 @@
package formatter package formatter
import ( import (
"fmt"
"strings" "strings"
"time" "time"
@ -391,7 +392,7 @@ func (ctx *serviceInspectContext) Ports() []swarm.PortConfig {
} }
const ( const (
defaultServiceTableFormat = "table {{.ID}}\t{{.Name}}\t{{.Mode}}\t{{.Replicas}}\t{{.Image}}" defaultServiceTableFormat = "table {{.ID}}\t{{.Name}}\t{{.Mode}}\t{{.Replicas}}\t{{.Image}}\t{{.Ports}}"
serviceIDHeader = "ID" serviceIDHeader = "ID"
modeHeader = "MODE" modeHeader = "MODE"
@ -410,7 +411,7 @@ func NewServiceListFormat(source string, quiet bool) Format {
if quiet { if quiet {
return `id: {{.ID}}` return `id: {{.ID}}`
} }
return `id: {{.ID}}\nname: {{.Name}}\nmode: {{.Mode}}\nreplicas: {{.Replicas}}\nimage: {{.Image}}\n` return `id: {{.ID}}\nname: {{.Name}}\nmode: {{.Mode}}\nreplicas: {{.Replicas}}\nimage: {{.Image}}\nports: {{.Ports}}\n`
} }
return Format(source) return Format(source)
} }
@ -439,6 +440,7 @@ func ServiceListWrite(ctx Context, services []swarm.Service, info map[string]Ser
"Mode": modeHeader, "Mode": modeHeader,
"Replicas": replicasHeader, "Replicas": replicasHeader,
"Image": imageHeader, "Image": imageHeader,
"Ports": portsHeader,
} }
return ctx.Write(&serviceCtx, render) return ctx.Write(&serviceCtx, render)
} }
@ -483,3 +485,20 @@ func (c *serviceContext) Image() string {
return image return image
} }
func (c *serviceContext) Ports() string {
if c.service.Spec.EndpointSpec == nil || c.service.Spec.EndpointSpec.Ports == nil {
return ""
}
ports := []string{}
for _, pConfig := range c.service.Spec.EndpointSpec.Ports {
if pConfig.PublishMode == swarm.PortConfigPublishModeIngress {
ports = append(ports, fmt.Sprintf("*:%d->%d/%s",
pConfig.PublishedPort,
pConfig.TargetPort,
pConfig.Protocol,
))
}
}
return strings.Join(ports, ",")
}

View File

@ -29,9 +29,9 @@ func TestServiceContextWrite(t *testing.T) {
// Table format // Table format
{ {
Context{Format: NewServiceListFormat("table", false)}, Context{Format: NewServiceListFormat("table", false)},
`ID NAME MODE REPLICAS IMAGE `ID NAME MODE REPLICAS IMAGE PORTS
id_baz baz global 2/4 id_baz baz global 2/4 *:80->8080/tcp
id_bar bar replicated 2/4 id_bar bar replicated 2/4 *:80->8080/tcp
`, `,
}, },
{ {
@ -62,12 +62,14 @@ name: baz
mode: global mode: global
replicas: 2/4 replicas: 2/4
image: image:
ports: *:80->8080/tcp
id: id_bar id: id_bar
name: bar name: bar
mode: replicated mode: replicated
replicas: 2/4 replicas: 2/4
image: image:
ports: *:80->8080/tcp
`, `,
}, },
@ -88,8 +90,38 @@ bar
for _, testcase := range cases { for _, testcase := range cases {
services := []swarm.Service{ services := []swarm.Service{
{ID: "id_baz", Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: "baz"}}}, {
{ID: "id_bar", Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: "bar"}}}, ID: "id_baz",
Spec: swarm.ServiceSpec{
Annotations: swarm.Annotations{Name: "baz"},
EndpointSpec: &swarm.EndpointSpec{
Ports: []swarm.PortConfig{
{
PublishMode: "ingress",
PublishedPort: 80,
TargetPort: 8080,
Protocol: "tcp",
},
},
},
},
},
{
ID: "id_bar",
Spec: swarm.ServiceSpec{
Annotations: swarm.Annotations{Name: "bar"},
EndpointSpec: &swarm.EndpointSpec{
Ports: []swarm.PortConfig{
{
PublishMode: "ingress",
PublishedPort: 80,
TargetPort: 8080,
Protocol: "tcp",
},
},
},
},
},
} }
info := map[string]ServiceListInfo{ info := map[string]ServiceListInfo{
"id_baz": { "id_baz": {
@ -114,8 +146,38 @@ bar
func TestServiceContextWriteJSON(t *testing.T) { func TestServiceContextWriteJSON(t *testing.T) {
services := []swarm.Service{ services := []swarm.Service{
{ID: "id_baz", Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: "baz"}}}, {
{ID: "id_bar", Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: "bar"}}}, ID: "id_baz",
Spec: swarm.ServiceSpec{
Annotations: swarm.Annotations{Name: "baz"},
EndpointSpec: &swarm.EndpointSpec{
Ports: []swarm.PortConfig{
{
PublishMode: "ingress",
PublishedPort: 80,
TargetPort: 8080,
Protocol: "tcp",
},
},
},
},
},
{
ID: "id_bar",
Spec: swarm.ServiceSpec{
Annotations: swarm.Annotations{Name: "bar"},
EndpointSpec: &swarm.EndpointSpec{
Ports: []swarm.PortConfig{
{
PublishMode: "ingress",
PublishedPort: 80,
TargetPort: 8080,
Protocol: "tcp",
},
},
},
},
},
} }
info := map[string]ServiceListInfo{ info := map[string]ServiceListInfo{
"id_baz": { "id_baz": {
@ -128,8 +190,8 @@ func TestServiceContextWriteJSON(t *testing.T) {
}, },
} }
expectedJSONs := []map[string]interface{}{ expectedJSONs := []map[string]interface{}{
{"ID": "id_baz", "Name": "baz", "Mode": "global", "Replicas": "2/4", "Image": ""}, {"ID": "id_baz", "Name": "baz", "Mode": "global", "Replicas": "2/4", "Image": "", "Ports": "*:80->8080/tcp"},
{"ID": "id_bar", "Name": "bar", "Mode": "replicated", "Replicas": "2/4", "Image": ""}, {"ID": "id_bar", "Name": "bar", "Mode": "replicated", "Replicas": "2/4", "Image": "", "Ports": "*:80->8080/tcp"},
} }
out := bytes.NewBufferString("") out := bytes.NewBufferString("")