docker/swarmkit

View on GitHub
swarmd/cmd/swarmctl/common/resolver.go

Summary

Maintainability
A
50 mins
Test Coverage
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
}