github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/context/export.go (about) 1 package context 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "os" 9 10 "github.com/docker/cli/cli" 11 "github.com/docker/cli/cli/command" 12 "github.com/docker/cli/cli/context/kubernetes" 13 "github.com/docker/cli/cli/context/store" 14 "github.com/spf13/cobra" 15 "k8s.io/client-go/tools/clientcmd" 16 ) 17 18 // ExportOptions are the options used for exporting a context 19 type ExportOptions struct { 20 Kubeconfig bool 21 ContextName string 22 Dest string 23 } 24 25 func newExportCommand(dockerCli command.Cli) *cobra.Command { 26 opts := &ExportOptions{} 27 cmd := &cobra.Command{ 28 Use: "export [OPTIONS] CONTEXT [FILE|-]", 29 Short: "Export a context to a tar or kubeconfig file", 30 Args: cli.RequiresRangeArgs(1, 2), 31 RunE: func(cmd *cobra.Command, args []string) error { 32 opts.ContextName = args[0] 33 if len(args) == 2 { 34 opts.Dest = args[1] 35 } else { 36 opts.Dest = opts.ContextName 37 if opts.Kubeconfig { 38 opts.Dest += ".kubeconfig" 39 } else { 40 opts.Dest += ".dockercontext" 41 } 42 } 43 return RunExport(dockerCli, opts) 44 }, 45 } 46 47 flags := cmd.Flags() 48 flags.BoolVar(&opts.Kubeconfig, "kubeconfig", false, "Export as a kubeconfig file") 49 flags.SetAnnotation("kubeconfig", "kubernetes", nil) 50 flags.SetAnnotation("kubeconfig", "deprecated", nil) 51 return cmd 52 } 53 54 func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error { 55 var writer io.Writer 56 var printDest bool 57 if dest == "-" { 58 if dockerCli.Out().IsTerminal() { 59 return errors.New("cowardly refusing to export to a terminal, please specify a file path") 60 } 61 writer = dockerCli.Out() 62 } else { 63 f, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) 64 if err != nil { 65 return err 66 } 67 defer f.Close() 68 writer = f 69 printDest = true 70 } 71 if _, err := io.Copy(writer, reader); err != nil { 72 return err 73 } 74 if printDest { 75 fmt.Fprintf(dockerCli.Err(), "Written file %q\n", dest) 76 } 77 return nil 78 } 79 80 // RunExport exports a Docker context 81 func RunExport(dockerCli command.Cli, opts *ExportOptions) error { 82 if err := store.ValidateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName { 83 return err 84 } 85 ctxMeta, err := dockerCli.ContextStore().GetMetadata(opts.ContextName) 86 if err != nil { 87 return err 88 } 89 if !opts.Kubeconfig { 90 reader := store.Export(opts.ContextName, dockerCli.ContextStore()) 91 defer reader.Close() 92 return writeTo(dockerCli, reader, opts.Dest) 93 } 94 kubernetesEndpointMeta := kubernetes.EndpointFromContext(ctxMeta) 95 if kubernetesEndpointMeta == nil { 96 return fmt.Errorf("context %q has no kubernetes endpoint", opts.ContextName) 97 } 98 kubernetesEndpoint, err := kubernetesEndpointMeta.WithTLSData(dockerCli.ContextStore(), opts.ContextName) 99 if err != nil { 100 return err 101 } 102 kubeConfig := kubernetesEndpoint.KubernetesConfig() 103 rawCfg, err := kubeConfig.RawConfig() 104 if err != nil { 105 return err 106 } 107 data, err := clientcmd.Write(rawCfg) 108 if err != nil { 109 return err 110 } 111 return writeTo(dockerCli, bytes.NewBuffer(data), opts.Dest) 112 }