kubectl.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package commands
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. api "github.com/porter-dev/porter/api/client"
  8. "github.com/porter-dev/porter/api/types"
  9. "github.com/porter-dev/porter/cli/cmd/config"
  10. "github.com/spf13/cobra"
  11. )
  12. func registerCommand_Kubectl(cliConf config.CLIConfig) *cobra.Command {
  13. kubectlCmd := &cobra.Command{
  14. Use: "kubectl",
  15. Short: "Use kubectl to interact with a Porter cluster",
  16. Run: func(cmd *cobra.Command, args []string) {
  17. err := checkLoginAndRunWithConfig(cmd, cliConf, args, runKubectl)
  18. if err != nil {
  19. os.Exit(1)
  20. }
  21. },
  22. }
  23. var printKubeconfig bool
  24. kubectlCmd.Flags().BoolVar(&printKubeconfig, "print-kubeconfig", false, "Print an authenticated kubeconfig to the console with a 15 minute expiry")
  25. return kubectlCmd
  26. }
  27. func runKubectl(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, featureFlags config.FeatureFlags, cmd *cobra.Command, args []string) error {
  28. _, err := exec.LookPath("kubectl")
  29. if err != nil {
  30. return fmt.Errorf("error finding kubectl: %w", err)
  31. }
  32. printKubeconfig, err := cmd.Flags().GetBool("print-kubeconfig")
  33. if err != nil {
  34. return fmt.Errorf("error when retrieving print-kubeconfig flag")
  35. }
  36. tmpFile, err := downloadTempKubeconfig(ctx, client, cliConf)
  37. if err != nil {
  38. return err
  39. }
  40. defer func() {
  41. os.Remove(tmpFile)
  42. }()
  43. if printKubeconfig {
  44. kc, err := os.ReadFile(tmpFile) //nolint:gosec
  45. if err != nil {
  46. return fmt.Errorf("erro reading downloaded kubeconfig for printing: %w", err)
  47. }
  48. fmt.Println(string(kc))
  49. return nil
  50. }
  51. err = os.Setenv("KUBECONFIG", tmpFile)
  52. if err != nil {
  53. return fmt.Errorf("unable to set KUBECONFIG env var: %w", err)
  54. }
  55. execCommand := exec.Command("kubectl", args...)
  56. execCommand.Stdin = os.Stdin
  57. execCommand.Stdout = os.Stdout
  58. execCommand.Stderr = os.Stderr
  59. err = execCommand.Run()
  60. if err != nil {
  61. return fmt.Errorf("error running helm: %w", err)
  62. }
  63. return nil
  64. }
  65. func downloadTempKubeconfig(ctx context.Context, client api.Client, cliConf config.CLIConfig) (string, error) {
  66. tmpFile, err := os.CreateTemp("", "porter_kubeconfig_*.yaml")
  67. if err != nil {
  68. return "", fmt.Errorf("error creating temp file for kubeconfig: %w", err)
  69. }
  70. defer tmpFile.Close()
  71. resp, err := client.GetKubeconfig(ctx, cliConf.Project, cliConf.Cluster, cliConf.Kubeconfig)
  72. if err != nil {
  73. return "", fmt.Errorf("error fetching kubeconfig for cluster: %w", err)
  74. }
  75. _, err = tmpFile.Write(resp.Kubeconfig)
  76. if err != nil {
  77. return "", fmt.Errorf("error writing kubeconfig to temp file: %w", err)
  78. }
  79. return tmpFile.Name(), nil
  80. }