| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- package commands
- import (
- "context"
- "fmt"
- "os"
- "os/exec"
- "strings"
- api "github.com/porter-dev/porter/api/client"
- "github.com/porter-dev/porter/api/types"
- "github.com/porter-dev/porter/cli/cmd/config"
- "github.com/spf13/cobra"
- )
- func registerCommand_Kubectl(cliConf config.CLIConfig) *cobra.Command {
- depMsg := `This command is no longer available. Please consult documentation of the respective cloud provider to get access to the kubeconfig of the cluster.
- Note that any change made directly on the kubernetes cluster under the hood can degrade the performance and reliability of the cluster, and Porter will
- automatically reconcile any changes that pose a threat to the uptime of the cluster to its original state. Porter is not responsible for the issues that
- arise due to the change implemented directly on the Kubernetes cluster via kubectl.`
- kubectlCmd := &cobra.Command{
- Use: "kubectl",
- Short: "Use kubectl to interact with a Porter cluster",
- Deprecated: depMsg,
- Run: func(cmd *cobra.Command, args []string) {
- err := checkLoginAndRunWithConfig(cmd, cliConf, args, runKubectl)
- if err != nil {
- os.Exit(1)
- }
- },
- }
- var printKubeconfig bool
- kubectlCmd.Flags().BoolVar(&printKubeconfig, "print-kubeconfig", false, "Print an authenticated kubeconfig to the console with a 15 minute expiry")
- return kubectlCmd
- }
- func runKubectl(ctx context.Context, _ *types.GetAuthenticatedUserResponse, client api.Client, cliConf config.CLIConfig, featureFlags config.FeatureFlags, cmd *cobra.Command, args []string) error {
- // this will never error because it just ran
- user, _ := client.AuthCheck(ctx)
- project, err := client.GetProject(ctx, cliConf.Project)
- if err != nil {
- return fmt.Errorf("could not retrieve project from Porter API. Please contact support@porter.run: %w", err)
- }
- if project == nil {
- return fmt.Errorf("project [%d] not found", cliConf.Project)
- }
- if !strings.HasSuffix(user.Email, "@porter.run") && project.ValidateApplyV2 {
- return fmt.Errorf("Forbidden")
- }
- _, err = exec.LookPath("kubectl")
- if err != nil {
- return fmt.Errorf("error finding kubectl: %w", err)
- }
- printKubeconfig, err := cmd.Flags().GetBool("print-kubeconfig")
- if err != nil {
- return fmt.Errorf("error when retrieving print-kubeconfig flag")
- }
- tmpFile, err := downloadTempKubeconfig(ctx, client, cliConf)
- if err != nil {
- return err
- }
- defer func() {
- os.Remove(tmpFile)
- }()
- if printKubeconfig {
- kc, err := os.ReadFile(tmpFile) //nolint:gosec
- if err != nil {
- return fmt.Errorf("erro reading downloaded kubeconfig for printing: %w", err)
- }
- fmt.Println(string(kc))
- return nil
- }
- err = os.Setenv("KUBECONFIG", tmpFile)
- if err != nil {
- return fmt.Errorf("unable to set KUBECONFIG env var: %w", err)
- }
- execCommand := exec.Command("kubectl", args...)
- execCommand.Stdin = os.Stdin
- execCommand.Stdout = os.Stdout
- execCommand.Stderr = os.Stderr
- err = execCommand.Run()
- if err != nil {
- return fmt.Errorf("error running kubectl: %w", err)
- }
- return nil
- }
- func downloadTempKubeconfig(ctx context.Context, client api.Client, cliConf config.CLIConfig) (string, error) {
- tmpFile, err := os.CreateTemp("", "porter_kubeconfig_*.yaml")
- if err != nil {
- return "", fmt.Errorf("error creating temp file for kubeconfig: %w", err)
- }
- defer tmpFile.Close()
- resp, err := client.GetKubeconfig(ctx, cliConf.Project, cliConf.Cluster, cliConf.Kubeconfig)
- if err != nil {
- return "", fmt.Errorf("error fetching kubeconfig for cluster: %w", err)
- }
- _, err = tmpFile.Write(resp.Kubeconfig)
- if err != nil {
- return "", fmt.Errorf("error writing kubeconfig to temp file: %w", err)
- }
- return tmpFile.Name(), nil
- }
|