github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/common/resolver.go (about)

     1  package common
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/docker/swarmkit/api"
     8  	"github.com/spf13/cobra"
     9  )
    10  
    11  // Resolver provides ID to Name resolution.
    12  type Resolver struct {
    13  	cmd   *cobra.Command
    14  	c     api.ControlClient
    15  	ctx   context.Context
    16  	cache map[string]string
    17  }
    18  
    19  // NewResolver creates a new Resolver.
    20  func NewResolver(cmd *cobra.Command, c api.ControlClient) *Resolver {
    21  	return &Resolver{
    22  		cmd:   cmd,
    23  		c:     c,
    24  		ctx:   Context(cmd),
    25  		cache: make(map[string]string),
    26  	}
    27  }
    28  
    29  func (r *Resolver) get(t interface{}, id string) string {
    30  	switch t.(type) {
    31  	case api.Node:
    32  		res, err := r.c.GetNode(r.ctx, &api.GetNodeRequest{NodeID: id})
    33  		if err != nil {
    34  			return id
    35  		}
    36  		if res.Node.Spec.Annotations.Name != "" {
    37  			return res.Node.Spec.Annotations.Name
    38  		}
    39  		if res.Node.Description == nil {
    40  			return id
    41  		}
    42  		return res.Node.Description.Hostname
    43  	case api.Service:
    44  		res, err := r.c.GetService(r.ctx, &api.GetServiceRequest{ServiceID: id})
    45  		if err != nil {
    46  			return id
    47  		}
    48  		return res.Service.Spec.Annotations.Name
    49  	case api.Task:
    50  		res, err := r.c.GetTask(r.ctx, &api.GetTaskRequest{TaskID: id})
    51  		if err != nil {
    52  			return id
    53  		}
    54  		svc := r.get(api.Service{}, res.Task.ServiceID)
    55  		return fmt.Sprintf("%s.%d", svc, res.Task.Slot)
    56  	default:
    57  		return id
    58  	}
    59  }
    60  
    61  // Resolve will attempt to resolve an ID to a Name by querying the manager.
    62  // Results are stored into a cache.
    63  // If the `-n` flag is used in the command-line, resolution is disabled.
    64  func (r *Resolver) Resolve(t interface{}, id string) string {
    65  	if r.cmd.Flags().Changed("no-resolve") {
    66  		return id
    67  	}
    68  	if name, ok := r.cache[id]; ok {
    69  		return name
    70  	}
    71  	name := r.get(t, id)
    72  	r.cache[id] = name
    73  	return name
    74  }