mirror of https://github.com/docker/cli.git
Add `PORTS` field for `docker service ls` (`ingress`)
This fix is related to 30232 wherw `docker service ls` does not show `PORTS` information like `docker service ps`. This fix adds `PORTS` fields for services that publish ports in ingress mode. Additional unit tests cases have been updated. This fix is related to 30232. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
parent
d37d03c9dc
commit
e0d4e672a1
|
@ -1,6 +1,7 @@
|
|||
package formatter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -391,7 +392,7 @@ func (ctx *serviceInspectContext) Ports() []swarm.PortConfig {
|
|||
}
|
||||
|
||||
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"
|
||||
modeHeader = "MODE"
|
||||
|
@ -410,7 +411,7 @@ func NewServiceListFormat(source string, quiet bool) Format {
|
|||
if quiet {
|
||||
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)
|
||||
}
|
||||
|
@ -439,6 +440,7 @@ func ServiceListWrite(ctx Context, services []swarm.Service, info map[string]Ser
|
|||
"Mode": modeHeader,
|
||||
"Replicas": replicasHeader,
|
||||
"Image": imageHeader,
|
||||
"Ports": portsHeader,
|
||||
}
|
||||
return ctx.Write(&serviceCtx, render)
|
||||
}
|
||||
|
@ -483,3 +485,20 @@ func (c *serviceContext) Image() string {
|
|||
|
||||
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, ",")
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ func TestServiceContextWrite(t *testing.T) {
|
|||
// Table format
|
||||
{
|
||||
Context{Format: NewServiceListFormat("table", false)},
|
||||
`ID NAME MODE REPLICAS IMAGE
|
||||
id_baz baz global 2/4
|
||||
id_bar bar replicated 2/4
|
||||
`ID NAME MODE REPLICAS IMAGE PORTS
|
||||
id_baz baz global 2/4 *:80->8080/tcp
|
||||
id_bar bar replicated 2/4 *:80->8080/tcp
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
@ -62,12 +62,14 @@ name: baz
|
|||
mode: global
|
||||
replicas: 2/4
|
||||
image:
|
||||
ports: *:80->8080/tcp
|
||||
|
||||
id: id_bar
|
||||
name: bar
|
||||
mode: replicated
|
||||
replicas: 2/4
|
||||
image:
|
||||
ports: *:80->8080/tcp
|
||||
|
||||
`,
|
||||
},
|
||||
|
@ -88,8 +90,38 @@ bar
|
|||
|
||||
for _, testcase := range cases {
|
||||
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{
|
||||
"id_baz": {
|
||||
|
@ -114,8 +146,38 @@ bar
|
|||
|
||||
func TestServiceContextWriteJSON(t *testing.T) {
|
||||
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{
|
||||
"id_baz": {
|
||||
|
@ -128,8 +190,8 @@ func TestServiceContextWriteJSON(t *testing.T) {
|
|||
},
|
||||
}
|
||||
expectedJSONs := []map[string]interface{}{
|
||||
{"ID": "id_baz", "Name": "baz", "Mode": "global", "Replicas": "2/4", "Image": ""},
|
||||
{"ID": "id_bar", "Name": "bar", "Mode": "replicated", "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": "", "Ports": "*:80->8080/tcp"},
|
||||
}
|
||||
|
||||
out := bytes.NewBufferString("")
|
||||
|
|
Loading…
Reference in New Issue