From 67333b8fa6415f27f64042ab824ee5e416c468da Mon Sep 17 00:00:00 2001 From: Josh Branham Date: Mon, 6 Jan 2025 10:23:05 -0700 Subject: [PATCH] Require a reason for using 'osdctl cluster ssh key' --- cmd/cluster/resize/infra_node.go | 2 +- cmd/cluster/ssh/key.go | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/cmd/cluster/resize/infra_node.go b/cmd/cluster/resize/infra_node.go index 358c13241..764165608 100644 --- a/cmd/cluster/resize/infra_node.go +++ b/cmd/cluster/resize/infra_node.go @@ -85,7 +85,7 @@ func newCmdResizeInfra() *cobra.Command { infraResizeCmd.Flags().StringVarP(&r.clusterId, "cluster-id", "C", "", "OCM internal/external cluster id or cluster name to resize infra nodes for.") infraResizeCmd.Flags().StringVar(&r.instanceType, "instance-type", "", "(optional) Override for an AWS or GCP instance type to resize the infra nodes to, by default supported instance types are automatically selected.") - infraResizeCmd.Flags().StringVar(&r.reason, "reason", "", "The reason for this command, which requires elevation, to be run (usualy an OHSS or PD ticket)") + infraResizeCmd.Flags().StringVar(&r.reason, "reason", "", "The reason for this command, which requires elevation, to be run (usually an OHSS or PD ticket)") infraResizeCmd.Flags().StringVar(&r.justification, "justification", "", "The justification behind resize") infraResizeCmd.MarkFlagRequired("cluster-id") diff --git a/cmd/cluster/ssh/key.go b/cmd/cluster/ssh/key.go index 42a3ad509..77b1cf22d 100644 --- a/cmd/cluster/ssh/key.go +++ b/cmd/cluster/ssh/key.go @@ -21,16 +21,18 @@ const ( privateKeyFilename = "ssh-privatekey" ) -var ( +type clusterSSHKeyOpts struct { + elevationReason string skipConfirmation bool -) +} func NewCmdKey() *cobra.Command { + opts := &clusterSSHKeyOpts{} cmd := &cobra.Command{ - Use: "key [cluster identifier]", + Use: "key [cluster identifier] --reason $reason", Short: "Retrieve a cluster's SSH key from Hive", Long: "Retrieve a cluster's SSH key from Hive. If a cluster identifier (internal ID, UUID, name, etc) is provided, then the key retrieved will be for that cluster. If no identifier is provided, then the key for the cluster backplane is currently logged into will be used instead. This command should only be used as a last resort, when all other means of accessing a node are lost.", - Example: `$ osdctl cluster ssh key $CLUSTER_ID + Example: `$ osdctl cluster ssh key $CLUSTER_ID --reason "OHSS-XXXX" INFO[0005] Backplane URL retrieved via OCM environment: https://api.backplane.openshift.com -----BEGIN RSA PRIVATE KEY----- ... @@ -39,7 +41,7 @@ INFO[0005] Backplane URL retrieved via OCM environment: https://api.backplane.op Providing a $CLUSTER_ID allows you to specify the cluster who's private ssh key you want to view, regardless if you're logged in or not. -$ osdctl cluster ssh key +$ osdctl cluster ssh key --reason "OHSS-XXXX" INFO[0005] Backplane URL retrieved via OCM environment: https://api.backplane.openshift.com -----BEGIN RSA PRIVATE KEY----- ... @@ -48,7 +50,7 @@ INFO[0005] Backplane URL retrieved via OCM environment: https://api.backplane.op Omitting the $CLUSTER_ID will print the ssh key for the cluster you're currently logged into. -$ osdctl cluster ssh key -y > /tmp/ssh.key +$ osdctl cluster ssh key -y --reason "OHSS-XXXX" > /tmp/ssh.key INFO[0005] Backplane URL retrieved via OCM environment: https://api.backplane.openshift.com $ cat /tmp/ssh.key -----BEGIN RSA PRIVATE KEY----- @@ -72,7 +74,7 @@ Despite the logs from backplane, the ssh key is the only output channelled throu clusterID = args[0] } - err = PrintKey(clusterID, skipConfirmation) + err = PrintKey(clusterID, opts) if err != nil { return fmt.Errorf("failed to retrieve ssh key for cluster %s: %w", clusterID, err) } @@ -80,13 +82,16 @@ Despite the logs from backplane, the ssh key is the only output channelled throu }, } - cmd.Flags().BoolVarP(&skipConfirmation, "yes", "y", false, "Skip any confirmation prompts and print the key automatically. Useful for redirects and scripting.") + cmd.Flags().BoolVarP(&opts.skipConfirmation, "yes", "y", false, "Skip any confirmation prompts and print the key automatically. Useful for redirects and scripting.") + cmd.Flags().StringVar(&opts.elevationReason, "reason", "", "Provide a reason for accessing the clusters SSH key, used for backplane. Eg: 'OHSS-XXXX', or '#ITN-2024-XXXXX") + + _ = cmd.MarkFlagRequired("reason") return cmd } // PrintKey retrieves the cluster's private ssh key from hive and prints it to stdout. -func PrintKey(identifier string, skipConfirmation bool) error { +func PrintKey(identifier string, opts *clusterSSHKeyOpts) error { // Login to the provided cluster's hive shard ocmClient, err := utils.CreateConnection() if err != nil { @@ -99,7 +104,7 @@ func PrintKey(identifier string, skipConfirmation bool) error { } // Print summary and confirm this is the intended cluster before proceeding - if !skipConfirmation { + if !opts.skipConfirmation { fmt.Println("Cluster:") fmt.Printf("\tName:\t%s\n", cluster.Name()) fmt.Printf("\tID:\t%s\n", cluster.ID()) @@ -119,7 +124,10 @@ func PrintKey(identifier string, skipConfirmation bool) error { scheme := runtime.NewScheme() corev1.AddToScheme(scheme) - hiveClient, err := k8s.NewAsBackplaneClusterAdmin(hive.ID(), client.Options{Scheme: scheme}) + hiveClient, err := k8s.NewAsBackplaneClusterAdmin(hive.ID(), client.Options{Scheme: scheme}, []string{ + opts.elevationReason, + fmt.Sprintf("Need elevation for %s hive cluster in order to get ssh key for %s", hive.ID(), clusterID), + }...) if err != nil { return fmt.Errorf("failed to create privileged client: %w", err) }