cmd

package
v0.0.0-...-1bd9ace Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2024 License: Apache-2.0 Imports: 63 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DeploySuccess is the successful deploy const.
	DeploySuccess = "successfulDeploy"
)

Variables

View Source
var APIKeyCmd = &cobra.Command{
	Use:   "api-key",
	Short: "Manage API keys for Pixie",
	Run: func(cmd *cobra.Command, args []string) {
		utils.Info("Nothing here... Please execute one of the subcommands")
		cmd.Help()
	},
}

APIKeyCmd is the api-key sub-command of the CLI.

View Source
var AuthCmd = &cobra.Command{
	Use:   "auth",
	Short: "Authenticate with Pixie",
	Run: func(cmd *cobra.Command, args []string) {
		utils.Info("Nothing here... Please execute one of the subcommands")
		cmd.Help()
	},
}

AuthCmd is the auth sub-command of the CLI.

View Source
var (
	AvailableCloudAddrs = []string{
		"getcosmic.ai:443",
		"withpixie.ai:443",
	}
)
View Source
var BlockListedLabels = []string{
	"vizier-bootstrap",
	"component",
	"vizier-updater-dep",
	"app",
}

BlockListedLabels are labels that we won't allow users to specify, since these are labels that we specify ourselves. Changing these may break the vizier update job.

View Source
var CLIUpdateCmd = &cobra.Command{
	Use:   "cli",
	Short: "Run updates of CLI",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("cli_version", cmd.Flags().Lookup("cli_version"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		selectedVersion := viper.GetString("cli_version")

		updater := update.NewCLIUpdater(viper.GetString("cloud_addr"))
		currVersion := version.GetVersion()
		if len(selectedVersion) == 0 {

			versions, err := updater.GetAvailableVersions(currVersion.Semver())
			if err != nil {
				utils.WithError(err).Fatal("Cannot determine new versions to update to.")
			}
			if len(versions) == 0 {
				utils.Info("No updates available")
				return
			}

			selectedVersion = versions[0]
			if len(selectedVersion) == 0 {
				return
			}
		}

		if ok, err := updater.IsUpdatable(); !ok || err != nil {
			utils.Fatal("Cannot perform update, it's likely the file is not in a writable path.")

		}

		if strings.Contains(strings.ToLower(currVersion.Builder()), "homebrew") {
			continueUpdate := components.YNPrompt(`Homebrew installation detected. Please use homebrew to update the cli.
Update anyway?`, false)
			if !continueUpdate {
				utils.Error("Update cancelled.")
				return
			}
		}

		if !strings.Contains(strings.ToLower(currVersion.Builder()), "jenkins") {
			continueUpdate := components.YNPrompt(`Uncommon CLI installation.
We recommend rebuilding/updating the CLI using the same method as the initial install.
Update anyway?`, false)
			if !continueUpdate {
				utils.Error("Update cancelled.")
				return
			}
		}

		utils.Infof("Updating to version: %s", selectedVersion)
		mustInstallVersion(updater, selectedVersion)
	},
}

CLIUpdateCmd is the cli subcommand of the "update" command.

View Source
var CollectLogsCmd = &cobra.Command{
	Use:   "collect-logs",
	Short: "Collect Pixie logs on the cluster",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("namespace", cmd.Flags().Lookup("namespace"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		c := k8s.NewLogCollector()
		fName := fmt.Sprintf("pixie_logs_%s.zip", time.Now().Format("20060102150405"))
		err := c.CollectPixieLogs(fName)
		if err != nil {
			log.WithError(err).Fatal("Failed to get log files")
		}

		utils.Infof("Logs written to %s", fName)
	},
}

CollectLogsCmd is the "deploy" command.

View Source
var CreateAPIKeyCmd = &cobra.Command{
	Use:   "create",
	Short: "Generate a API key for Pixie",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("desc", cmd.Flags().Lookup("desc"))
		viper.BindPFlag("short", cmd.Flags().Lookup("short"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		desc, _ := cmd.Flags().GetString("desc")
		short, _ := cmd.Flags().GetBool("short")

		keyID, key, err := generateAPIKey(cloudAddr, desc)
		if err != nil {

			log.WithError(err).Fatal("Failed to generate API key")
		}
		if short {
			fmt.Fprintf(os.Stdout, "%s\n", key)
		} else {
			utils.Infof("Generated API key: \nID: %s \nKey: %s", keyID, key)
		}
	},
}

CreateAPIKeyCmd is the Create sub-command of APIKey.

View Source
var CreateBundle = &cobra.Command{
	Use:   "create-bundle",
	Short: "Create a bundle for scripts",

	Hidden: true,
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("base", cmd.Flags().Lookup("base"))
		viper.BindPFlag("search_path", cmd.Flags().Lookup("search_path"))
		viper.BindPFlag("out", cmd.Flags().Lookup("out"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		basePaths, _ := cmd.Flags().GetStringArray("base")
		searchPaths, _ := cmd.Flags().GetStringArray("search_path")

		out, _ := cmd.Flags().GetString("out")
		b := script.NewBundleWriter(searchPaths, basePaths)
		err := b.Write(out)
		if err != nil {

			log.WithError(err).Fatal("Failed to create bundle")
		}
	},
}

CreateBundle is the 'create-bundle' command. It's used to create a script bundle that can be used by the UI/CLI. This is a temporary command until we have proper script persistence.

View Source
var CreateCloudCertsCmd = &cobra.Command{
	Use:    "create-cloud-certs",
	Short:  "Creates a yaml with server and client certs",
	Hidden: true,
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("namespace", cmd.Flags().Lookup("namespace"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		namespace, _ := cmd.Flags().GetString("namespace")
		yaml, err := certs.GenerateCloudCertYAMLs(namespace)
		if err != nil {
			fmt.Printf("error while creating service tls certs: %v", err)
			os.Exit(1)
		}
		fmt.Print(yaml)
	},
}

CreateCloudCertsCmd is the "create-cloud-certs" command.

View Source
var CreateDeployKeyCmd = &cobra.Command{
	Use:   "create",
	Short: "Generate a deploy key for Pixie",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("desc", cmd.Flags().Lookup("desc"))
		viper.BindPFlag("short", cmd.Flags().Lookup("short"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		desc := viper.GetString("desc")
		short, _ := cmd.Flags().GetBool("short")

		keyID, key, err := generateDeployKey(cloudAddr, desc)
		if err != nil {

			log.WithError(err).Fatal("Failed to generate deployment key")
		}
		if short {
			fmt.Fprintf(os.Stdout, "%s\n", key)
		} else {
			utils.Infof("Generated deployment key: \nID: %s \nKey: %s", keyID, key)
		}
	},
}

CreateDeployKeyCmd is the Create sub-command of DeployKey.

View Source
var DebugCmd = &cobra.Command{
	Use:    "debug",
	Short:  "Debug commands used by Pixie",
	Hidden: true,
}

DebugCmd has internal debug functionality.

View Source
var DebugContainersCmd = &cobra.Command{
	Use:   "containers",
	Short: "List vizier containers",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		selectedCluster, _ := cmd.Flags().GetString("cluster")
		plane, _ := cmd.Flags().GetString("plane")
		pods, err := fetchVizierPods(cloudAddr, selectedCluster, plane)
		if err != nil {
			utils.WithError(err).Fatal("Could not fetch Vizier pods")
		}
		w := components.CreateStreamWriter("table", os.Stdout)
		defer w.Finish()
		w.SetHeader("containers", []string{"Name", "Pod", "State", "Restarts", "Message", "Reason", "Start Time"})
		for _, pod := range pods {
			for _, c := range pod.ContainerStatuses {
				_ = w.Write([]interface{}{
					c.Name, pod.Name, c.ContainerState, c.RestartCount, c.Message, c.Reason, time.Unix(0, c.StartTimestampNS),
				})
			}
		}
	},
}

DebugContainersCmd is the containers debug command.

View Source
var DebugLogCmd = &cobra.Command{
	Use:   "log",
	Short: "Show log for vizier pods",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) != 1 {
			utils.Fatal("Must supply a single argument pod name")
		}

		podName := args[0]
		var err error

		cloudAddr := viper.GetString("cloud_addr")
		selectedCluster, _ := cmd.Flags().GetString("cluster")
		clusterID := uuid.FromStringOrNil(selectedCluster)
		container, _ := cmd.Flags().GetString("container")

		if clusterID == uuid.Nil {
			clusterID, err = getVizier(cloudAddr)
			if err != nil {
				utils.WithError(err).Fatal("Could not fetch healthy vizier")
			}
		}

		fmt.Printf("Pod Name: %s\n", podName)
		fmt.Printf("Cluster ID : %s\n", clusterID.String())
		fmt.Printf("Container: %s\n", container)

		conn, err := vizier.ConnectionToVizierByID(cloudAddr, clusterID)
		if err != nil {
			utils.WithError(err).Fatal("Could not connect to vizier")
		}

		prev, _ := cmd.Flags().GetBool("previous")
		ctx, cleanup := utils.WithSignalCancellable(context.Background())
		defer cleanup()
		resp, err := conn.DebugLogRequest(ctx, podName, prev, container)
		if err != nil {
			utils.WithError(err).Fatal("Logging failed")
		}

		for v := range resp {
			if v != nil {
				if v.Err != nil {
					utils.WithError(v.Err).Fatal("Failed to get logs")
				} else {
					fmt.Printf("%s", strings.ReplaceAll(v.Data, "\n",
						fmt.Sprintf("\n%s ", color.GreenString("[%s]", podName))))
				}
			}
		}
	},
}

DebugLogCmd is the log debug command.

View Source
var DebugPodsCmd = &cobra.Command{
	Use:   "pods",
	Short: "List vizier pods",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		selectedCluster, _ := cmd.Flags().GetString("cluster")
		plane, _ := cmd.Flags().GetString("plane")
		pods, err := fetchVizierPods(cloudAddr, selectedCluster, plane)
		if err != nil {
			utils.WithError(err).Fatal("Could not fetch Vizier pods")
		}
		w := components.CreateStreamWriter("table", os.Stdout)
		defer w.Finish()
		w.SetHeader("pods", []string{"Name", "Phase", "Restarts", "Message", "Reason", "Start Time"})
		for _, pod := range pods {
			_ = w.Write([]interface{}{
				pod.Name, pod.Phase, pod.RestartCount, pod.Message, pod.Reason, time.Unix(0, pod.CreatedAt),
			})
		}
	},
}

DebugPodsCmd is the pods debug command.

View Source
var DeleteAPIKeyCmd = &cobra.Command{
	Use:   "delete",
	Short: "Delete a API key for Pixie",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("id", cmd.Flags().Lookup("id"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		id, _ := cmd.Flags().GetString("id")
		if id == "" {
			utils.Fatal("API key ID must be specified using --id flag")
		}

		idUUID, err := uuid.FromString(id)
		if err != nil {
			utils.WithError(err).Fatal("Invalid API key ID")
		}

		err = deleteAPIKey(cloudAddr, idUUID)
		if err != nil {

			log.WithError(err).Fatal("Failed to delete API key")
		}
		utils.Info("Successfully deleted API key")
	},
}

DeleteAPIKeyCmd is the Delete sub-command of APIKey.

View Source
var DeleteCmd = &cobra.Command{
	Use:   "delete",
	Short: "Deletes Pixie on the current K8s cluster",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("clobber", cmd.Flags().Lookup("clobber"))
		viper.BindPFlag("namespace", cmd.Flags().Lookup("namespace"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		clobberAll, _ := cmd.Flags().GetBool("clobber")
		ns, _ := cmd.Flags().GetString("namespace")
		if ns == "" {
			ns = vizier.MustFindVizierNamespace()
		}
		deletePixie(ns, clobberAll)
	},
}

DeleteCmd is the "delete" command.

View Source
var DeleteDeployKeyCmd = &cobra.Command{
	Use:   "delete",
	Short: "Delete a deploy key for Pixie",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("id", cmd.Flags().Lookup("id"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		id, _ := cmd.Flags().GetString("id")

		if id == "" {
			utils.Fatal("Deployment key ID must be specified using --id flag")
		}

		idUUID, err := uuid.FromString(id)
		if err != nil {
			utils.WithError(err).Fatal("Invalid deployment key ID")
		}

		err = deleteDeployKey(cloudAddr, idUUID)
		if err != nil {

			log.WithError(err).Fatal("Failed to delete deployment key")
		}
		utils.Info("Successfully deleted deployment key")
	},
}

DeleteDeployKeyCmd is the Delete sub-command of DeployKey.

View Source
var DemoCmd = &cobra.Command{
	Use:   "demo",
	Short: "Manage demo apps",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {

		if cmd.PersistentFlags().Lookup("artifacts") != nil {
			viper.BindPFlag("artifacts", cmd.PersistentFlags().Lookup("artifacts"))
			return
		}
		viper.BindPFlag("artifacts", cmd.Parent().PersistentFlags().Lookup("artifacts"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		utils.Info("Nothing here... Please execute one of the subcommands")
		cmd.Help()
	},
}

DemoCmd is the demo sub-command of the CLI to deploy and delete demo apps.

View Source
var DeployCmd = &cobra.Command{
	Use:   "deploy",
	Short: "Deploys Pixie on the current K8s cluster",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("extract_yaml", cmd.Flags().Lookup("extract_yaml"))
		viper.BindPFlag("vizier_version", cmd.Flags().Lookup("vizier_version"))
		viper.BindPFlag("check", cmd.Flags().Lookup("check"))
		viper.BindPFlag("check_only", cmd.Flags().Lookup("check_only"))
		viper.BindPFlag("namespace", cmd.Flags().Lookup("namespace"))
		viper.BindPFlag("deploy_key", cmd.Flags().Lookup("deploy_key"))
		viper.BindPFlag("use_etcd_operator", cmd.Flags().Lookup("use_etcd_operator"))
		viper.BindPFlag("labels", cmd.Flags().Lookup("labels"))
		viper.BindPFlag("annotations", cmd.Flags().Lookup("annotations"))
		viper.BindPFlag("cluster_name", cmd.Flags().Lookup("cluster_name"))
		viper.BindPFlag("pem_memory_limit", cmd.Flags().Lookup("pem_memory_limit"))
		viper.BindPFlag("pem_memory_request", cmd.Flags().Lookup("pem_memory_request"))
		viper.BindPFlag("patches", cmd.Flags().Lookup("patches"))
		viper.BindPFlag("pem_flags", cmd.Flags().Lookup("pem_flags"))
		viper.BindPFlag("operator_version", cmd.Flags().Lookup("operator_version"))
		viper.BindPFlag("deploy_olm", cmd.Flags().Lookup("deploy_olm"))
		viper.BindPFlag("olm_namespace", cmd.Flags().Lookup("olm_namespace"))
		viper.BindPFlag("olm_operator_namespace", cmd.Flags().Lookup("olm_operator_namespace"))
		viper.BindPFlag("data_access", cmd.Flags().Lookup("data_access"))
		viper.BindPFlag("datastream_buffer_size", cmd.Flags().Lookup("datastream_buffer_size"))
		viper.BindPFlag("datastream_buffer_spike_size", cmd.Flags().Lookup("datastream_buffer_spike_size"))
		viper.BindPFlag("disable_auto_update", cmd.Flags().Lookup("disable_auto_update"))
	},
	PostRun: func(cmd *cobra.Command, args []string) {
		if cmd.Annotations["status"] != DeploySuccess {
			return
		}

		p := func(s string, a ...interface{}) {
			fmt.Fprintf(os.Stderr, s, a...)
		}
		u := color.New(color.Underline).Sprintf
		b := color.New(color.Bold).Sprintf
		g := color.GreenString

		cloudAddr := viper.GetString("cloud_addr")
		docsAddr := cloudAddr
		if !slices.Contains(AvailableCloudAddrs, cloudAddr) {
			docsAddr = "px.dev"
		}

		fmt.Fprint(os.Stderr, "\n")
		p(color.CyanString("==> ") + b("Next Steps:\n"))
		p("\nRun some scripts using the %s cli. For example: \n", g("px"))
		p("- %s : to show pre-installed scripts.\n", g("px script list"))
		p("- %s : to run service info for sock-shop demo application (service selection coming soon!).\n",
			g("px run %s", script.ServiceStatsScript))
		p("\nCheck out our docs: %s.\n", u("https://docs.%s", docsAddr))
		p("\nVisit : %s to use Pixie's UI.\n", u("https://work.%s", cloudAddr))
	},
	Run: runDeployCmd,
}

DeployCmd is the "deploy" command.

View Source
var DeployKeyCmd = &cobra.Command{
	Use:   "deploy-key",
	Short: "Manage deployment keys for Pixie",
	Run: func(cmd *cobra.Command, args []string) {
		utils.Info("Nothing here... Please execute one of the subcommands")
		cmd.Help()
	},
}

DeployKeyCmd is the deploy-key sub-command of the CLI.

View Source
var GetAPIKeyCmd = &cobra.Command{
	Use:   "get",
	Short: "Get API key details for a specific key",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		if len(args) != 1 {
			utils.Fatal("Expected a single argument 'key id'.")
		}

		keyID, err := uuid.FromString(args[0])
		if err != nil {
			utils.Fatal("Malformed Key ID. Expected a single argument 'key id'.")
		}
		k, err := getAPIKey(cloudAddr, keyID)
		if err != nil {

			log.WithError(err).Fatal("Failed to fetch API key")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("api-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), k.Key, k.CreatedAt,
			k.Desc})
	},
}

GetAPIKeyCmd is the List sub-command of APIKey.

View Source
var GetClusterCmd = &cobra.Command{
	Use:   "cluster",
	Short: "Get information about the current kubeconfig cluster",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("id", cmd.Flags().Lookup("id"))
		viper.BindPFlag("cloud-addr", cmd.Flags().Lookup("cloud-addr"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		id, _ := cmd.Flags().GetBool("id")
		addr, _ := cmd.Flags().GetBool("cloud-addr")

		config := k8s.GetConfig()

		clusterID := vizier.GetClusterIDFromKubeConfig(config)

		if clusterID == uuid.Nil {
			cliUtils.Infof("Unable to find Pixie cluster running in current kubeconfig")
		}

		cloudAddr := vizier.GetCloudAddrFromKubeConfig(config)

		if id {
			fmt.Fprintf(os.Stdout, "%s\n", clusterID)
			return
		}

		if addr {
			fmt.Fprintf(os.Stdout, "%s\n", cloudAddr)
			return
		}

		cliUtils.Infof("Cluster ID: %s\nCloud Address: %s", clusterID, cloudAddr)
	},
}

GetClusterCmd is the "get cluster" command to get information about the current kubeconfig cluster.

View Source
var GetCmd = &cobra.Command{
	Use:   "get",
	Short: "Get information about cluster/edge modules",
}

GetCmd is the "get" command.

View Source
var GetDeployKeyCmd = &cobra.Command{
	Use:   "get",
	Short: "Get deployment key details for a single key",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		if len(args) != 1 {
			utils.Fatal("Expected a single argument 'key id'.")
		}

		keyID, err := uuid.FromString(args[0])
		if err != nil {
			utils.Fatal("Malformed Key ID. Expected a single argument 'key id'.")
		}
		k, err := getDeployKeys(cloudAddr, keyID)
		if err != nil {

			log.WithError(err).Fatal("Failed to list deployment keys")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("deployment-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), k.Key, k.CreatedAt,
			k.Desc})
	},
}

GetDeployKeyCmd is the List sub-command of DeployKey.

View Source
var GetPEMsCmd = &cobra.Command{
	Use:     "pems",
	Aliases: []string{"agents", "pem"},
	Short:   "Get information about running pems",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)
		br := mustCreateBundleReader()
		execScript := br.MustGetScript(script.AgentStatusScript)

		allClusters, _ := cmd.Flags().GetBool("all-clusters")
		selectedCluster, _ := cmd.Flags().GetString("cluster")
		clusterID := uuid.FromStringOrNil(selectedCluster)
		var err error
		if !allClusters && clusterID == uuid.Nil {
			clusterID, err = vizier.GetCurrentVizier(cloudAddr)
			if err != nil {
				cliUtils.WithError(err).Fatal("Could not fetch healthy vizier")
			}
		}

		conns := vizier.MustConnectHealthyDefaultVizier(cloudAddr, allClusters, clusterID)

		ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
		defer cancel()
		if err := vizier.RunScriptAndOutputResults(ctx, conns, execScript, format, false); err != nil {
			cliUtils.Fatalf("Script failed: %s", vizier.FormatErrorMessage(err))
		}
	},
}

GetPEMsCmd is the "get pem" command.

View Source
var GetViziersCmd = &cobra.Command{
	Use:     "viziers",
	Aliases: []string{"clusters"},
	Short:   "Get information about registered viziers",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		l, err := vizier.NewLister(cloudAddr)
		if err != nil {

			log.WithError(err).Fatal("Failed to create Vizier lister")
		}
		vzs, err := l.GetViziersInfo()
		if err != nil {

			log.WithError(err).Fatalln("Failed to get vizier information")
		}

		sort.Slice(vzs, func(i, j int) bool { return vzs[i].ClusterName < vzs[j].ClusterName })

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("viziers", []string{"ClusterName", "ID", "K8s Version", "Operator Version", "Vizier Version", "Last Heartbeat", "Status", "Status Message"})

		for _, vz := range vzs {
			var lastHeartbeat interface{}
			lastHeartbeat = vz.LastHeartbeatNs
			if format == "" || format == "table" {
				if vz.LastHeartbeatNs >= 0 {
					lastHeartbeat = humanize.Time(
						time.Unix(0,
							time.Since(time.Unix(0, vz.LastHeartbeatNs)).Nanoseconds()))
				}
			}
			_ = w.Write([]interface{}{vz.ClusterName, utils.UUIDFromProtoOrNil(vz.ID), vz.ClusterVersion,
				prettyVersion(vz.OperatorVersion), prettyVersion(vz.VizierVersion), lastHeartbeat, vz.Status, vz.StatusMessage})
		}
	},
}

GetViziersCmd is the "get viziers" command.

View Source
var ListAPIKeyCmd = &cobra.Command{
	Use:   "list",
	Short: "List all API key metadata",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("output", cmd.Flags().Lookup("output"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		keys, err := listAPIKeyMetadatas(cloudAddr)
		if err != nil {

			log.WithError(err).Fatal("Failed to list API keys")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("api-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		for _, k := range keys {
			_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), "<hidden>", k.CreatedAt,
				k.Desc})
		}
	},
}

ListAPIKeyCmd is the List sub-command of APIKey.

View Source
var ListDeployKeyCmd = &cobra.Command{
	Use:   "list",
	Short: "List all deployment key metadata",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("output", cmd.Flags().Lookup("output"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		keys, err := listDeployKeys(cloudAddr)
		if err != nil {

			log.WithError(err).Fatal("Failed to list deployment keys")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("deployment-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		for _, k := range keys {
			_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), "<hidden>", k.CreatedAt,
				k.Desc})
		}
	},
}

ListDeployKeyCmd is the List sub-command of DeployKey.

View Source
var LiveCmd = &cobra.Command{
	Use:   "live",
	Short: "Interactive Pixie Views",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")

		useNewAC, _ := cmd.Flags().GetBool("new_autocomplete")

		br := mustCreateBundleReader()
		var execScript *script.ExecutableScript
		var err error
		scriptFile, _ := cmd.Flags().GetString("file")
		var scriptArgs []string

		if scriptFile == "" {
			if len(args) > 0 {
				scriptName := args[0]
				execScript = br.MustGetScript(scriptName)
				scriptArgs = args[1:]
			}
		} else {
			execScript, err = loadScriptFromFile(scriptFile)
			if err != nil {
				utils.WithError(err).Fatal("Failed to get query string")
			}
			scriptArgs = args
		}

		if execScript != nil {
			fs := execScript.GetFlagSet()
			if fs != nil {
				if err := fs.Parse(scriptArgs); err != nil {
					if err == flag.ErrHelp {
						os.Exit(0)
					}
					utils.WithError(err).Fatal("Failed to parse script flags")
				}
				err := execScript.UpdateFlags(fs)
				if err != nil {
					utils.WithError(err).Fatal("Error parsing script flags")
				}
			}
		}

		cloudConn, err := utils.GetCloudClientConnection(cloudAddr)
		if err != nil {

			log.WithError(err).Fatal("Could not connect to cloud")
		}
		aClient := cloudpb.NewAutocompleteServiceClient(cloudConn)
		allClusters, _ := cmd.Flags().GetBool("all-clusters")
		selectedCluster, _ := cmd.Flags().GetString("cluster")
		clusterUUID := uuid.FromStringOrNil(selectedCluster)
		if !allClusters && clusterUUID == uuid.Nil {
			clusterUUID, err = vizier.GetCurrentVizier(cloudAddr)
			if err != nil {
				utils.WithError(err).Fatal("Could not fetch healthy vizier")
			}
		}

		useEncryption, _ := cmd.Flags().GetBool("e2e_encryption")

		viziers := vizier.MustConnectHealthyDefaultVizier(cloudAddr, allClusters, clusterUUID)
		lv, err := live.New(br, viziers, cloudAddr, aClient, execScript, useNewAC, useEncryption, clusterUUID)
		if err != nil {
			utils.WithError(err).Fatal("Failed to initialize live view")
		}

		if err := lv.Run(); err != nil {
			utils.WithError(err).Fatal("Failed to run live view")
		}
	},
}

LiveCmd is the "query" command.

View Source
var LoginCmd = &cobra.Command{
	Use:   "login",
	Short: "Login to Pixie",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("manual", cmd.PersistentFlags().Lookup("manual"))
		viper.BindPFlag("use_api_key", cmd.Flags().Lookup("use_api_key"))
		viper.BindPFlag("api_key", cmd.Flags().Lookup("api_key"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		l := auth.PixieCloudLogin{
			ManualMode: viper.GetBool("manual"),
			CloudAddr:  viper.GetString("cloud_addr"),
			UseAPIKey:  viper.GetBool("use_api_key"),
			APIKey:     viper.GetString("api_key"),
		}
		var refreshToken *auth.RefreshToken
		var err error
		if refreshToken, err = l.Run(); err != nil {

			log.WithError(err).Fatal("Failed to login")
		}
		if err = auth.SaveRefreshToken(refreshToken); err != nil {

			log.WithError(err).Fatal("Failed to persist auth token")
		}

		if token, _ := jwt.Parse([]byte(refreshToken.Token)); token != nil {
			userID := srvutils.GetUserID(token)
			if userID != "" {

				_ = pxanalytics.Client().Enqueue(&analytics.Alias{
					UserId:     pxconfig.Cfg().UniqueClientID,
					PreviousId: userID,
				})
			}
		}
		utils.Info("Authentication Successful")
	},
}

LoginCmd is the Login sub-command of Auth.

View Source
var LookupAPIKeyCmd = &cobra.Command{
	Use:   "lookup",
	Short: "Lookup API key based on the value of the key",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)
		apiKey, err := cmd.Flags().GetString("key")
		if err != nil || len(apiKey) == 0 {
			fmt.Print("\nEnter API Key (won't echo): ")
			k, err := term.ReadPassword(syscall.Stdin)
			if err != nil {
				log.WithError(err).Fatal("Failed to read API Key")
			}
			apiKey = string(k)
		}

		k, err := lookupAPIKey(cloudAddr, apiKey)
		if err != nil {

			log.WithError(err).Fatal("Failed to list lookup key")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("api-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), "<hidden>", k.CreatedAt,
			k.Desc})
	},
}

LookupAPIKeyCmd is looks up the API key using the actual key value;

View Source
var LookupDeployKeyCmd = &cobra.Command{
	Use:   "lookup",
	Short: "Lookup deployment key based on the value of the key",
	Run: func(cmd *cobra.Command, args []string) {
		cloudAddr := viper.GetString("cloud_addr")
		format, _ := cmd.Flags().GetString("output")
		format = strings.ToLower(format)

		deployKey, err := cmd.Flags().GetString("key")
		if err != nil || len(deployKey) == 0 {
			fmt.Print("\nEnter Deploy Key (won't echo): ")
			k, err := term.ReadPassword(syscall.Stdin)
			if err != nil {
				log.WithError(err).Fatal("Failed to read Deploy Key")
			}
			deployKey = string(k)
		}

		k, err := lookupDeployKeys(cloudAddr, deployKey)
		if err != nil {

			log.WithError(err).Fatal("Failed to list deployment keys")
		}

		w := components.CreateStreamWriter(format, os.Stdout)
		defer w.Finish()
		w.SetHeader("api-keys", []string{"ID", "Key", "CreatedAt", "Description"})
		_ = w.Write([]interface{}{utils2.UUIDFromProtoOrNil(k.ID), "<hidden>", k.CreatedAt,
			k.Desc})
	},
}

LookupDeployKeyCmd is the List sub-command of DeployKey.

View Source
var RootCmd = &cobra.Command{
	Use:   "px",
	Short: "Pixie CLI",

	Long: `The Pixie command line interface.`,
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		printEnvVars()

		cloudAddr := getCloudAddrIfRequired(cmd)

		if matched, err := regexp.MatchString(".+:[0-9]+$", cloudAddr); !matched && err == nil {
			viper.Set("cloud_addr", cloudAddr+":443")
		}

		if viper.IsSet("testing_env") && !viper.IsSet("dev_cloud_namespace") {

			viper.Set("dev_cloud_namespace", "plc-dev")
		}

		p := cmd

		if p != nil {
			_ = pxanalytics.Client().Enqueue(&analytics.Track{
				UserId: pxconfig.Cfg().UniqueClientID,
				Event:  "Exec CMD",
				Properties: analytics.NewProperties().
					Set("cmd", p.Name()),
			})
		}

		for p != nil && p != UpdateCmd {
			p = p.Parent()
		}

		if p == UpdateCmd {
			return
		}
		versionStr := update.UpdatesAvailable(viper.GetString("cloud_addr"))
		if versionStr != "" {
			cmdName := "<NONE>"
			if p != nil {
				cmdName = p.Name()
			}

			_ = pxanalytics.Client().Enqueue(&analytics.Track{
				UserId: pxconfig.Cfg().UniqueClientID,
				Event:  "Update Available",
				Properties: analytics.NewProperties().
					Set("cmd", cmdName),
			})
			c := color.New(color.Bold, color.FgGreen)
			_, _ = c.Fprintf(os.Stderr, "Update to version \"%s\" available. Run \"px update cli\" to update.\n", versionStr)
		}

		checkAuthForCmd(cmd)

		cmd.VisitParents(checkAuthForCmd)
	},
}

RootCmd is the base command for Cobra.

View Source
var RunCmd = createNewCobraCommand()

RunCmd is the "query" command.

View Source
var RunSubCmd = createNewCobraCommand()

RunSubCmd is the "query" command used as a subcommand with scripts.

View Source
var ScriptCmd = &cobra.Command{
	Use:     "script",
	Short:   "Get information about pre-registered scripts",
	Aliases: []string{"scripts"},
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("bundle", cmd.PersistentFlags().Lookup("bundle"))
	},
}

ScriptCmd is the "script" command.

View Source
var ScriptListCmd = &cobra.Command{
	Use:     "list",
	Short:   "List pre-registered pxl scripts",
	Aliases: []string{"scripts"},
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("output_format", cmd.Flags().Lookup("output"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		br := mustCreateBundleReader()
		listBundleScripts(br, viper.GetString("output_format"))
	},
}

ScriptListCmd is the "script list" command.

View Source
var ScriptShowCmd = &cobra.Command{
	Use:     "show",
	Short:   "Dumps out the string for a particular pxl script",
	Args:    cobra.ExactArgs(1),
	Aliases: []string{"scripts"},
	Run: func(cmd *cobra.Command, args []string) {
		br := mustCreateBundleReader()
		scriptName := args[0]
		execScript := br.MustGetScript(scriptName)
		err := quick.Highlight(os.Stdout, execScript.ScriptString, "python3", "terminal16m", "monokai")
		if err != nil {
			fmt.Fprint(os.Stdout, execScript.ScriptString)
		}
	},
}

ScriptShowCmd is the "script show" command.

View Source
var UpdateCmd = &cobra.Command{
	Use:   "update",
	Short: "Update Pixie/CLI",
	Run: func(cmd *cobra.Command, args []string) {
		utils.Info("Nothing here... Please execute one of the subcommands")
		cmd.Help()
	},
}

UpdateCmd is the "update" sub-command of the CLI.

View Source
var VersionCmd = &cobra.Command{
	Use:   "version",
	Short: "Print the version number of the cli",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Printf("%s\n", version.GetVersion().ToString())
	},
}

VersionCmd is the "version" command.

View Source
var VizierUpdateCmd = &cobra.Command{
	Use:     "vizier",
	Aliases: []string{"platform", "pixie"},
	Short:   "Run updates of Pixie Platform",
	PreRun: func(cmd *cobra.Command, args []string) {
		viper.BindPFlag("vizier_version", cmd.Flags().Lookup("vizier_version"))
		viper.BindPFlag("redeploy_etcd", cmd.Flags().Lookup("redeploy_etcd"))
	},
	Run: func(cmd *cobra.Command, args []string) {
		versionString := viper.GetString("vizier_version")
		cloudAddr := viper.GetString("cloud_addr")
		redeployEtcd := viper.GetBool("redeploy_etcd")

		clusterID := uuid.Nil
		clusterStr, _ := cmd.Flags().GetString("cluster")
		if len(clusterStr) > 0 {
			u, err := uuid.FromString(clusterStr)
			if err != nil {
				utils.WithError(err).Fatal("Failed to parse cluster argument")
			}
			clusterID = u
		}

		cloudConn, err := utils.GetCloudClientConnection(cloudAddr)
		if err != nil {

			log.Fatalln(err)
		}

		if clusterID == uuid.Nil {
			clusterID, err = vizier.GetCurrentOrFirstHealthyVizier(cloudAddr)
			if err != nil {
				utils.WithError(err).Fatal("Failed to select cluster")
			}
		}
		clusterInfo, err := vizier.GetVizierInfo(cloudAddr, clusterID)
		if err != nil {
			utils.WithError(err).Fatalf("Failed to get info for cluster: %s", clusterID.String())
		}

		utils.Infof("Updating Pixie on the following cluster: %s", clusterInfo.ClusterName)
		clusterOk := components.YNPrompt("Is the cluster correct?", true)
		if !clusterOk {
			utils.Error("Cluster is not correct. Aborting.")
			return
		}

		if len(versionString) == 0 {

			versionString, err = getLatestVizierVersion(cloudConn)
			if err != nil {

				log.WithError(err).Fatal("Failed to fetch Vizier versions")
			}
		}

		if sv, err := semver.Parse(clusterInfo.VizierVersion); err == nil {
			svNew := semver.MustParse(versionString)
			if svNew.Compare(sv) < 0 {
				utils.Fatalf("Cannot upgrade current version %s to requested older version %s",
					sv.String(), svNew.String())
			}
		}

		_ = pxanalytics.Client().Enqueue(&analytics.Track{
			UserId: pxconfig.Cfg().UniqueClientID,
			Event:  "Vizier Update Initiated",
			Properties: analytics.NewProperties().
				Set("cloud_addr", cloudAddr).
				Set("cluster_id", utils2.UUIDFromProtoOrNil(clusterInfo.ID)).
				Set("cluster_status", clusterInfo.Status.String()),
		})

		utils.Infof("Updating to version: %s", versionString)

		ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
		defer cancel()
		updateJobs := []utils.Task{
			newTaskWrapper("Initiating update", func() error {
				return initiateUpdate(ctx, cloudConn, clusterID, versionString, redeployEtcd)
			}),
			newTaskWrapper("Wait for update to complete (this may take a few minutes)", func() error {
				timer := time.NewTicker(5 * time.Second)
				timeout := time.NewTimer(5 * time.Minute)
				defer timer.Stop()
				defer timeout.Stop()
				for {
					select {
					case <-timer.C:
						clusterInfo, err := vizier.GetVizierInfo(cloudAddr, clusterID)
						if err != nil {
							return err
						}
						if clusterInfo.Status == cloudpb.CS_HEALTHY {
							updateVersion, err := semver.Parse(versionString)
							if err != nil {
								return err
							}
							currentVersion, err := semver.Parse(clusterInfo.VizierVersion)
							if err != nil {
								return err
							}

							if currentVersion.Compare(updateVersion) == 0 {
								return nil
							}
						}
					case <-timeout.C:
						return errors.New("timeout waiting for update")
					}
				}
			}),
			newTaskWrapper("Wait for healthcheck", waitForHealthCheckTaskGenerator(cloudAddr, clusterID)),
		}
		uj := utils.NewSerialTaskRunner(updateJobs)
		err = uj.RunAndMonitor()

		if err != nil {
			_ = pxanalytics.Client().Enqueue(&analytics.Track{
				UserId: pxconfig.Cfg().UniqueClientID,
				Event:  "Vizier Update Failed",
				Properties: analytics.NewProperties().
					Set("cloud_addr", cloudAddr).
					Set("cluster_id", clusterID),
			})

			log.WithError(err).Fatal("Update failed")
		}

		_ = pxanalytics.Client().Enqueue(&analytics.Track{
			UserId: pxconfig.Cfg().UniqueClientID,
			Event:  "Vizier Update Complete",
			Properties: analytics.NewProperties().
				Set("cloud_addr", cloudAddr).
				Set("cluster_id", clusterID),
		})
	},
}

VizierUpdateCmd is the command used to update Vizier.

Functions

func Asset

func Asset(name string) ([]byte, error)

Asset loads and returns the asset for the given name. It returns an error if the asset could not be found or could not be loaded.

func AssetDir

func AssetDir(name string) ([]string, error)

AssetDir returns the file names below a certain directory embedded in the file by go-bindata. For example if you run go-bindata on data/... and data contains the following hierarchy:

data/
  foo.txt
  img/
    a.png
    b.png

then AssetDir("data") would return []string{"foo.txt", "img"} AssetDir("data/img") would return []string{"a.png", "b.png"} AssetDir("foo.txt") and AssetDir("notexist") would return an error AssetDir("") will return []string{"data"}.

func AssetInfo

func AssetInfo(name string) (os.FileInfo, error)

AssetInfo loads and returns the asset info for the given name. It returns an error if the asset could not be found or could not be loaded.

func AssetNames

func AssetNames() []string

AssetNames returns the names of the assets.

func Execute

func Execute()

Execute is the main function for the Cobra CLI.

func MustAsset

func MustAsset(name string) []byte

MustAsset is like Asset but panics when Asset would return an error. It simplifies safe initialization of global variables.

func RestoreAsset

func RestoreAsset(dir, name string) error

RestoreAsset restores an asset under the given directory

func RestoreAssets

func RestoreAssets(dir, name string) error

RestoreAssets restores an asset under the given directory recursively

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL