github.com/panekj/cli@v0.0.0-20230304125325-467dd2f3797e/cli/command/idresolver/idresolver.go (about)

     1  package idresolver
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/docker/docker/api/types"
     7  	"github.com/docker/docker/api/types/swarm"
     8  	"github.com/docker/docker/client"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  // IDResolver provides ID to Name resolution.
    13  type IDResolver struct {
    14  	client    client.APIClient
    15  	noResolve bool
    16  	cache     map[string]string
    17  }
    18  
    19  // New creates a new IDResolver.
    20  func New(client client.APIClient, noResolve bool) *IDResolver {
    21  	return &IDResolver{
    22  		client:    client,
    23  		noResolve: noResolve,
    24  		cache:     make(map[string]string),
    25  	}
    26  }
    27  
    28  func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, error) {
    29  	switch t.(type) {
    30  	case swarm.Node:
    31  		node, _, err := r.client.NodeInspectWithRaw(ctx, id)
    32  		if err != nil {
    33  			return id, nil
    34  		}
    35  		if node.Spec.Annotations.Name != "" {
    36  			return node.Spec.Annotations.Name, nil
    37  		}
    38  		if node.Description.Hostname != "" {
    39  			return node.Description.Hostname, nil
    40  		}
    41  		return id, nil
    42  	case swarm.Service:
    43  		service, _, err := r.client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
    44  		if err != nil {
    45  			return id, nil
    46  		}
    47  		return service.Spec.Annotations.Name, nil
    48  	default:
    49  		return "", errors.Errorf("unsupported type")
    50  	}
    51  }
    52  
    53  // Resolve will attempt to resolve an ID to a Name by querying the manager.
    54  // Results are stored into a cache.
    55  // If the `-n` flag is used in the command-line, resolution is disabled.
    56  func (r *IDResolver) Resolve(ctx context.Context, t interface{}, id string) (string, error) {
    57  	if r.noResolve {
    58  		return id, nil
    59  	}
    60  	if name, ok := r.cache[id]; ok {
    61  		return name, nil
    62  	}
    63  	name, err := r.get(ctx, t, id)
    64  	if err != nil {
    65  		return "", err
    66  	}
    67  	r.cache[id] = name
    68  	return name, nil
    69  }