diff --git a/cmd/apps/inletsoperator_app.go b/cmd/apps/inletsoperator_app.go index 8196d4644..4b1b17668 100644 --- a/cmd/apps/inletsoperator_app.go +++ b/cmd/apps/inletsoperator_app.go @@ -4,7 +4,9 @@ package apps import ( + "bytes" "fmt" + "io" "io/ioutil" "log" "os" @@ -46,6 +48,29 @@ func MakeInstallInletsOperator() *cobra.Command { inletsOperator.Flags().String("pro-client-image", "", "Docker image for inlets-pro's client") inletsOperator.Flags().StringArray("set", []string{}, "Use custom flags or override existing flags \n(example --set image=org/repo:tag)") + inletsOperator.PreRunE = func(command *cobra.Command, args []string) error { + tokenFileName, _ := command.Flags().GetString("token-file") + tokenString, _ := command.Flags().GetString("token") + + if len(tokenFileName) > 0 && len(tokenString) > 0 { + return fmt.Errorf(`--token-file or --access-key is a required field for your cloud API token or service account JSON`) + } + if len(tokenFileName) > 0 { + if _, err := os.Stat(tokenFileName); err != nil { + return err + } + } + + secretKeyFile, _ := command.Flags().GetString("secret-key-file") + if len(secretKeyFile) > 0 { + if _, err := os.Stat(secretKeyFile); err != nil { + return err + } + } + + return nil + } + inletsOperator.RunE = func(command *cobra.Command, args []string) error { kubeConfigPath, _ := command.Flags().GetString("kubeconfig") if err := config.SetKubeconfig(kubeConfigPath); err != nil { @@ -65,11 +90,8 @@ func MakeInstallInletsOperator() *cobra.Command { } clientArch, clientOS := env.GetClientArch() - fmt.Printf("Client: %q, %q\n", clientArch, clientOS) - log.Printf("User dir established as: %s\n", userPath) - os.Setenv("HELM_HOME", path.Join(userPath, ".helm")) _, err = helm.TryDownloadHelm(userPath, clientArch, clientOS) @@ -101,42 +123,40 @@ func MakeInstallInletsOperator() *cobra.Command { tokenFileName, _ := command.Flags().GetString("token-file") tokenString, _ := command.Flags().GetString("token") - var accessKeyFrom, accessKeyValue string + s := Secret{ + Namespace: namespace, + Name: "inlets-access-key", + } if len(tokenFileName) > 0 { - accessKeyFrom = "--from-file" - accessKeyValue = tokenFileName - } else if len(tokenString) > 0 { - accessKeyFrom = "--from-literal" - accessKeyValue = tokenString + s.Literals = append(s.Literals, SecretLiteral{ + Name: "inlets-access-key", + FromFile: tokenFileName, + }) } else { - return fmt.Errorf(`--token-file or --access-key is a required field for your cloud API token or service account JSON`) + s.Literals = append(s.Literals, SecretLiteral{ + Name: "inlets-access-key", + FromValue: tokenString, + }) } - res, err := k8s.KubectlTask("create", "secret", "generic", - "inlets-access-key", - "--namespace="+namespace, - accessKeyFrom, "inlets-access-key="+accessKeyValue) - + err = applySecret(s) if err != nil { return err - } else if len(res.Stderr) > 0 && strings.Contains(res.Stderr, "AlreadyExists") { - fmt.Println("[Warning] secret inlets-access-key already exists and will be used.") - } else if len(res.Stderr) > 0 { - return fmt.Errorf("error from kubectl\n%q", res.Stderr) } secretKeyFile, _ := command.Flags().GetString("secret-key-file") - if len(secretKeyFile) > 0 { - res, err := k8s.KubectlTask("create", "secret", "generic", - "inlets-secret-key", - "--namespace="+namespace, - "--from-file", "inlets-secret-key="+secretKeyFile) - if len(res.Stderr) > 0 && strings.Contains(res.Stderr, "AlreadyExists") { - fmt.Println("[Warning] secret inlets-access-key already exists and will be used.") - } else if len(res.Stderr) > 0 { - return fmt.Errorf("error from kubectl\n%q", res.Stderr) - } else if err != nil { + s := Secret{ + Namespace: namespace, + Name: "inlets-secret-key", + } + s.Literals = append(s.Literals, SecretLiteral{ + Name: "inlets-access-key", + FromFile: secretKeyFile, + }) + + err = applySecret(s) + if err != nil { return err } } @@ -305,3 +325,46 @@ const inletsOperatorPostInstallMsg = `========================================== = inlets-operator has been installed. = =======================================================================` + "\n\n" + InletsOperatorInfoMsg + "\n\n" + pkg.ThanksForUsing + +type Secret struct { + Namespace string + Name string + Stdin io.Reader + Literals []SecretLiteral +} + +type SecretLiteral struct { + Name string + FromFile string + FromValue string +} + +func applySecret(s Secret) error { + parts := []string{"create", "secret", "generic", s.Name, "--dry-run=client", "-o=yaml"} + + for _, l := range s.Literals { + if len(l.FromFile) > 0 { + parts = append(parts, "--from-file", s.Name+"="+l.FromFile) + } else { + parts = append(parts, "--from-literal", s.Name+"="+l.FromValue) + } + } + + res, err := k8s.KubectlTask(parts...) + + if err != nil { + return err + } else if len(res.Stderr) > 0 && strings.Contains(res.Stderr, "Warning") == false { + return fmt.Errorf("error from kubectl\n%q", res.Stderr) + } + + manifest := bytes.NewReader([]byte(res.Stdout)) + res, err = k8s.KubectlTaskStdin(manifest, "apply", "-f", "-") + + if err != nil { + return err + } else if len(res.Stderr) > 0 && strings.Contains(res.Stderr, "Warning") == false { + return fmt.Errorf("error from kubectl\n%q", res.Stderr) + } + return nil +} diff --git a/go.mod b/go.mod index 2acc366e4..420c8cf20 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/alexellis/arkade go 1.13 require ( - github.com/alexellis/go-execute v0.0.0-20191207085904-961405ea7544 + github.com/alexellis/go-execute v0.0.0-20201205082949-69a2cde04f4f github.com/cheggaaa/pb/v3 v3.0.5 github.com/fatih/color v1.9.0 // indirect github.com/morikuni/aec v1.0.0 diff --git a/go.sum b/go.sum index 96b7bd520..90ecf931d 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alexellis/go-execute v0.0.0-20191207085904-961405ea7544 h1:KjtKgzxk/0wfp7vZxWUYPMiEJKep7FJ7C7o/vtHyc/Q= -github.com/alexellis/go-execute v0.0.0-20191207085904-961405ea7544/go.mod h1:zfRbgnPVxXCSpiKrg1CE72hNUWInqxExiaz2D9ppTts= +github.com/alexellis/go-execute v0.0.0-20201205082949-69a2cde04f4f h1:5auqirFmPvQPu2Cq8gSKPyT6l7KYr9UniEbmvOBiWXM= +github.com/alexellis/go-execute v0.0.0-20201205082949-69a2cde04f4f/go.mod h1:zfRbgnPVxXCSpiKrg1CE72hNUWInqxExiaz2D9ppTts= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= diff --git a/pkg/k8s/kubernetes_exec.go b/pkg/k8s/kubernetes_exec.go index 1f30f424a..8c35bf8a6 100644 --- a/pkg/k8s/kubernetes_exec.go +++ b/pkg/k8s/kubernetes_exec.go @@ -5,6 +5,7 @@ package k8s import ( "fmt" + "io" "strings" "github.com/alexellis/arkade/pkg/types" @@ -19,7 +20,18 @@ func GetNodeArchitecture() string { return arch } +func KubectlTaskStdin(reader io.Reader, parts ...string) (execute.ExecResult, error) { + task := execute.ExecTask{ + Command: "kubectl", + Args: parts, + StreamStdio: false, + Stdin: reader, + } + res, err := task.Execute() + + return res, err +} func KubectlTask(parts ...string) (execute.ExecResult, error) { task := execute.ExecTask{ Command: "kubectl",