github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/cli/command/context/update.go (about)

     1  package context
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/khulnasoft/cli/cli"
     8  	"github.com/khulnasoft/cli/cli/command"
     9  	"github.com/khulnasoft/cli/cli/command/formatter/tabwriter"
    10  	"github.com/khulnasoft/cli/cli/context/docker"
    11  	"github.com/khulnasoft/cli/cli/context/store"
    12  	"github.com/pkg/errors"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  // UpdateOptions are the options used to update a context
    17  type UpdateOptions struct {
    18  	Name        string
    19  	Description string
    20  	Docker      map[string]string
    21  }
    22  
    23  func longUpdateDescription() string {
    24  	buf := bytes.NewBuffer(nil)
    25  	buf.WriteString("Update a context\n\nDocker endpoint config:\n\n")
    26  	tw := tabwriter.NewWriter(buf, 20, 1, 3, ' ', 0)
    27  	fmt.Fprintln(tw, "NAME\tDESCRIPTION")
    28  	for _, d := range dockerConfigKeysDescriptions {
    29  		fmt.Fprintf(tw, "%s\t%s\n", d.name, d.description)
    30  	}
    31  	tw.Flush()
    32  	buf.WriteString("\nExample:\n\n$ docker context update my-context --description \"some description\" --docker \"host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file\"\n")
    33  	return buf.String()
    34  }
    35  
    36  func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
    37  	opts := &UpdateOptions{}
    38  	cmd := &cobra.Command{
    39  		Use:   "update [OPTIONS] CONTEXT",
    40  		Short: "Update a context",
    41  		Args:  cli.ExactArgs(1),
    42  		RunE: func(cmd *cobra.Command, args []string) error {
    43  			opts.Name = args[0]
    44  			return RunUpdate(dockerCli, opts)
    45  		},
    46  		Long: longUpdateDescription(),
    47  	}
    48  	flags := cmd.Flags()
    49  	flags.StringVar(&opts.Description, "description", "", "Description of the context")
    50  	flags.StringToStringVar(&opts.Docker, "docker", nil, "set the docker endpoint")
    51  	return cmd
    52  }
    53  
    54  // RunUpdate updates a Docker context
    55  func RunUpdate(dockerCLI command.Cli, o *UpdateOptions) error {
    56  	if err := store.ValidateContextName(o.Name); err != nil {
    57  		return err
    58  	}
    59  	s := dockerCLI.ContextStore()
    60  	c, err := s.GetMetadata(o.Name)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	dockerContext, err := command.GetDockerContext(c)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	if o.Description != "" {
    69  		dockerContext.Description = o.Description
    70  	}
    71  
    72  	c.Metadata = dockerContext
    73  
    74  	tlsDataToReset := make(map[string]*store.EndpointTLSData)
    75  
    76  	if o.Docker != nil {
    77  		dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(s, o.Docker)
    78  		if err != nil {
    79  			return errors.Wrap(err, "unable to create docker endpoint config")
    80  		}
    81  		c.Endpoints[docker.DockerEndpoint] = dockerEP
    82  		tlsDataToReset[docker.DockerEndpoint] = dockerTLS
    83  	}
    84  	if err := validateEndpoints(c); err != nil {
    85  		return err
    86  	}
    87  	if err := s.CreateOrUpdate(c); err != nil {
    88  		return err
    89  	}
    90  	for ep, tlsData := range tlsDataToReset {
    91  		if err := s.ResetEndpointTLSMaterial(o.Name, ep, tlsData); err != nil {
    92  			return err
    93  		}
    94  	}
    95  
    96  	fmt.Fprintln(dockerCLI.Out(), o.Name)
    97  	fmt.Fprintf(dockerCLI.Err(), "Successfully updated context %q\n", o.Name)
    98  	return nil
    99  }
   100  
   101  func validateEndpoints(c store.Metadata) error {
   102  	_, err := command.GetDockerContext(c)
   103  	return err
   104  }