Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSD-27572: Require a reason for using osdctl cluster ssh key #646

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/cluster/resize/infra_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
30 changes: 19 additions & 11 deletions cmd/cluster/ssh/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -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-----
...
Expand All @@ -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-----
...
Expand All @@ -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-----
Expand All @@ -72,21 +74,24 @@ 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)
}
return nil
},
}

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 {
Expand All @@ -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())
Expand All @@ -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)
}
Expand Down