github.com/itscaro/cli@v0.0.0-20190705081621-c9db0fe93829/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 return cmd 50 } 51 52 func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error { 53 var writer io.Writer 54 var printDest bool 55 if dest == "-" { 56 if dockerCli.Out().IsTerminal() { 57 return errors.New("cowardly refusing to export to a terminal, please specify a file path") 58 } 59 writer = dockerCli.Out() 60 } else { 61 f, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) 62 if err != nil { 63 return err 64 } 65 defer f.Close() 66 writer = f 67 printDest = true 68 } 69 if _, err := io.Copy(writer, reader); err != nil { 70 return err 71 } 72 if printDest { 73 fmt.Fprintf(dockerCli.Err(), "Written file %q\n", dest) 74 } 75 return nil 76 } 77 78 // RunExport exports a Docker context 79 func RunExport(dockerCli command.Cli, opts *ExportOptions) error { 80 if err := validateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName { 81 return err 82 } 83 ctxMeta, err := dockerCli.ContextStore().GetMetadata(opts.ContextName) 84 if err != nil { 85 return err 86 } 87 if !opts.Kubeconfig { 88 reader := store.Export(opts.ContextName, dockerCli.ContextStore()) 89 defer reader.Close() 90 return writeTo(dockerCli, reader, opts.Dest) 91 } 92 kubernetesEndpointMeta := kubernetes.EndpointFromContext(ctxMeta) 93 if kubernetesEndpointMeta == nil { 94 return fmt.Errorf("context %q has no kubernetes endpoint", opts.ContextName) 95 } 96 kubernetesEndpoint, err := kubernetesEndpointMeta.WithTLSData(dockerCli.ContextStore(), opts.ContextName) 97 if err != nil { 98 return err 99 } 100 kubeConfig := kubernetesEndpoint.KubernetesConfig() 101 rawCfg, err := kubeConfig.RawConfig() 102 if err != nil { 103 return err 104 } 105 data, err := clientcmd.Write(rawCfg) 106 if err != nil { 107 return err 108 } 109 return writeTo(dockerCli, bytes.NewBuffer(data), opts.Dest) 110 }