|
| 1 | +package accessrequest |
| 2 | + |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "fmt" |
| 6 | + "strings" |
| 7 | + "time" |
| 8 | + |
| 9 | + "github.com/openshift/backplane-cli/pkg/accessrequest" |
| 10 | + |
| 11 | + ocmcli "github.com/openshift-online/ocm-cli/pkg/ocm" |
| 12 | + "github.com/openshift/backplane-cli/pkg/login" |
| 13 | + "github.com/openshift/backplane-cli/pkg/utils" |
| 14 | + logger "github.com/sirupsen/logrus" |
| 15 | + "github.com/spf13/cobra" |
| 16 | +) |
| 17 | + |
| 18 | +var ( |
| 19 | + options struct { |
| 20 | + reason string |
| 21 | + notificationIssueID string |
| 22 | + pendingDuration time.Duration |
| 23 | + approvalDuration time.Duration |
| 24 | + } |
| 25 | +) |
| 26 | + |
| 27 | +// newCreateAccessRequestCmd returns cobra command |
| 28 | +func newCreateAccessRequestCmd() *cobra.Command { |
| 29 | + cmd := &cobra.Command{ |
| 30 | + Use: "create", |
| 31 | + Short: "Creates a new pending access request", |
| 32 | + Args: cobra.ExactArgs(0), |
| 33 | + SilenceUsage: true, |
| 34 | + SilenceErrors: true, |
| 35 | + RunE: runCreateAccessRequest, |
| 36 | + } |
| 37 | + |
| 38 | + cmd.Flags().StringVarP( |
| 39 | + &options.reason, |
| 40 | + "reason", |
| 41 | + "r", |
| 42 | + "", |
| 43 | + "Reason/justification passed through the access request to the customer. "+ |
| 44 | + "Reason will be read from the kube context (unless --cluster-id is set) or prompted if the option is not set.") |
| 45 | + |
| 46 | + cmd.Flags().StringVarP( |
| 47 | + &options.notificationIssueID, |
| 48 | + "notification-issue", |
| 49 | + "n", |
| 50 | + "", |
| 51 | + "JIRA issue used for notifications when the access request is approved or denied. "+ |
| 52 | + "Issue needs to belong to the OHSS project on production and to the SDAINT project for staging & integration. "+ |
| 53 | + "Issue will automatically be created in the proper project if the option is not set.") |
| 54 | + |
| 55 | + cmd.Flags().DurationVarP( |
| 56 | + &options.approvalDuration, |
| 57 | + "approval-duration", |
| 58 | + "d", |
| 59 | + 8*time.Hour, |
| 60 | + "The maximal period of time during which the access request can stay approved") |
| 61 | + |
| 62 | + return cmd |
| 63 | +} |
| 64 | + |
| 65 | +func retrieveOrPromptReason(cmd *cobra.Command) string { |
| 66 | + if utils.CheckValidPrompt() { |
| 67 | + clusterKey, err := cmd.Flags().GetString("cluster-id") |
| 68 | + |
| 69 | + if err == nil && clusterKey == "" { |
| 70 | + config, err := utils.ReadKubeconfigRaw() |
| 71 | + |
| 72 | + if err == nil { |
| 73 | + reasons := login.GetElevateContextReasons(config) |
| 74 | + for _, reason := range reasons { |
| 75 | + if reason != "" { |
| 76 | + fmt.Printf("Reason for elevations read from the kube config: %s\n", reason) |
| 77 | + if strings.ToLower(utils.AskQuestionFromPrompt("Do you want to use this as the reason/justification for the access request to create (Y/n)? ")) != "n" { |
| 78 | + return reason |
| 79 | + } |
| 80 | + break |
| 81 | + } |
| 82 | + } |
| 83 | + } else { |
| 84 | + logger.Warnf("won't extract the elevation reason from the kube context which failed to be read: %v", err) |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + return utils.AskQuestionFromPrompt("Please enter a reason/justification for the access request to create: ") |
| 90 | +} |
| 91 | + |
| 92 | +// runCreateAccessRequest creates access request for the given cluster |
| 93 | +func runCreateAccessRequest(cmd *cobra.Command, args []string) error { |
| 94 | + clusterID, err := accessrequest.GetClusterID(cmd) |
| 95 | + if err != nil { |
| 96 | + return fmt.Errorf("failed to compute cluster ID: %v", err) |
| 97 | + } |
| 98 | + |
| 99 | + ocmConnection, err := ocmcli.NewConnection().Build() |
| 100 | + if err != nil { |
| 101 | + return fmt.Errorf("failed to create OCM connection: %v", err) |
| 102 | + } |
| 103 | + defer ocmConnection.Close() |
| 104 | + |
| 105 | + accessRequest, err := accessrequest.GetAccessRequest(ocmConnection, clusterID) |
| 106 | + |
| 107 | + if err != nil { |
| 108 | + return err |
| 109 | + } |
| 110 | + |
| 111 | + if accessRequest != nil { |
| 112 | + accessrequest.PrintAccessRequest(clusterID, accessRequest) |
| 113 | + |
| 114 | + return fmt.Errorf("there is already an active access request for cluster '%s', eventually consider expiring it running 'ocm-backplane accessrequest expire'", clusterID) |
| 115 | + } |
| 116 | + |
| 117 | + reason := options.reason |
| 118 | + if reason == "" { |
| 119 | + reason = retrieveOrPromptReason(cmd) |
| 120 | + if reason == "" { |
| 121 | + return errors.New("no reason/justification, consider using the --reason option with a non empty string") |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + accessRequest, err = accessrequest.CreateAccessRequest(ocmConnection, clusterID, reason, options.notificationIssueID, options.approvalDuration) |
| 126 | + |
| 127 | + if err != nil { |
| 128 | + return err |
| 129 | + } |
| 130 | + |
| 131 | + accessrequest.PrintAccessRequest(clusterID, accessRequest) |
| 132 | + |
| 133 | + return nil |
| 134 | +} |
0 commit comments