swarmd/cmd/swarmctl/common/resolver.go
package common
import (
"context"
"fmt"
"github.com/moby/swarmkit/v2/api"
"github.com/spf13/cobra"
)
// Resolver provides ID to Name resolution.
type Resolver struct {
cmd *cobra.Command
c api.ControlClient
ctx context.Context
cache map[string]string
}
// NewResolver creates a new Resolver.
func NewResolver(cmd *cobra.Command, c api.ControlClient) *Resolver {
return &Resolver{
cmd: cmd,
c: c,
ctx: Context(cmd),
cache: make(map[string]string),
}
}
func (r *Resolver) get(t interface{}, id string) string {
switch t.(type) {
case api.Node:
res, err := r.c.GetNode(r.ctx, &api.GetNodeRequest{NodeID: id})
if err != nil {
return id
}
if res.Node.Spec.Annotations.Name != "" {
return res.Node.Spec.Annotations.Name
}
if res.Node.Description == nil {
return id
}
return res.Node.Description.Hostname
case api.Service:
res, err := r.c.GetService(r.ctx, &api.GetServiceRequest{ServiceID: id})
if err != nil {
return id
}
return res.Service.Spec.Annotations.Name
case api.Task:
res, err := r.c.GetTask(r.ctx, &api.GetTaskRequest{TaskID: id})
if err != nil {
return id
}
svc := r.get(api.Service{}, res.Task.ServiceID)
return fmt.Sprintf("%s.%d", svc, res.Task.Slot)
default:
return id
}
}
// Resolve will attempt to resolve an ID to a Name by querying the manager.
// Results are stored into a cache.
// If the `-n` flag is used in the command-line, resolution is disabled.
func (r *Resolver) Resolve(t interface{}, id string) string {
if r.cmd.Flags().Changed("no-resolve") {
return id
}
if name, ok := r.cache[id]; ok {
return name
}
name := r.get(t, id)
r.cache[id] = name
return name
}