Skip to content

Commit

Permalink
OSD-24269: Add cluster login support via OHSS card (#478)
Browse files Browse the repository at this point in the history
* Add JIRA client

* Add Jira Client

* OSD-24269:Enable login to cluster via OHSS card

* OSD-24269: Refactor Jira client with issue service
  • Loading branch information
samanthajayasinghe committed Jul 15, 2024
1 parent 7ab551e commit 1699359
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ mock-gen:
mockgen -destination=./pkg/cli/session/mocks/sessionMock.go -package=mocks github.com/openshift/backplane-cli/pkg/cli/session BackplaneSessionInterface
mockgen -destination=./pkg/utils/mocks/shellCheckerMock.go -package=mocks github.com/openshift/backplane-cli/pkg/utils ShellCheckerInterface
mockgen -destination=./pkg/pagerduty/mocks/clientMock.go -package=mocks github.com/openshift/backplane-cli/pkg/pagerduty PagerDutyClient
mockgen -destination=./pkg/utils/mocks/jiraMock.go -package=mocks github.com/openshift/backplane-cli/pkg/utils IssueServiceInterface
mockgen -destination=./pkg/jira/mocks/jiraMock.go -package=mocks github.com/openshift/backplane-cli/pkg/jira IssueServiceInterface

.PHONY: build-image
build-image:
Expand Down
45 changes: 41 additions & 4 deletions cmd/ocm-backplane/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/openshift/backplane-cli/pkg/backplaneapi"
"github.com/openshift/backplane-cli/pkg/cli/config"
"github.com/openshift/backplane-cli/pkg/cli/globalflags"
"github.com/openshift/backplane-cli/pkg/jira"
"github.com/openshift/backplane-cli/pkg/login"
"github.com/openshift/backplane-cli/pkg/ocm"
"github.com/openshift/backplane-cli/pkg/pagerduty"
Expand All @@ -36,6 +37,7 @@ const (
LoginTypeClusterID = "cluster-id"
LoginTypeExistingKubeConfig = "kube-config"
LoginTypePagerduty = "pagerduty"
LoginTypeJira = "jira"
)

var (
Expand All @@ -44,6 +46,7 @@ var (
kubeConfigPath string
pd string
defaultNamespace string
ohss string
}

// loginType derive the login type based on flags and args
Expand All @@ -62,7 +65,7 @@ var (
run oc command later to operate the target cluster.`,
Example: " backplane login <id>\n backplane login %test%\n backplane login <external_id>\n backplane login --pd <incident-id>",
Args: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Lookup("pd").Changed {
if cmd.Flags().Lookup("pd").Changed || cmd.Flags().Lookup("ohss").Changed {
if err := cobra.ExactArgs(0)(cmd, args); err != nil {
return err
}
Expand All @@ -77,6 +80,9 @@ var (
RunE: runLogin,
SilenceUsage: true,
}

//ohss service
ohssService *jira.OHSSService
)

func init() {
Expand Down Expand Up @@ -112,6 +118,12 @@ func init() {
"default",
"The default namespace for a user to execute commands in",
)
flags.StringVar(
&args.ohss,
"ohss",
"",
"Login using JIRA Id",
)

}

Expand Down Expand Up @@ -140,7 +152,16 @@ func runLogin(cmd *cobra.Command, argv []string) (err error) {
}
clusterKey = info.ClusterID
elevateReason = info.WebURL

case LoginTypeJira:
ohssIssue, err := getClusterInfoFromJira()
if err != nil {
return err
}
if ohssIssue.ClusterID == "" {
return fmt.Errorf("clusterID cannot be detected for JIRA issue:%s", args.ohss)
}
clusterKey = ohssIssue.ClusterID
elevateReason = ohssIssue.WebURL
case LoginTypeClusterID:
logger.Debugf("Cluster Key is given in argument")
clusterKey = argv[0]
Expand Down Expand Up @@ -571,9 +592,11 @@ func preLogin(cmd *cobra.Command, argv []string) (err error) {
loginType = LoginTypeClusterID

case 0:
if args.pd == "" {
if args.pd == "" && args.ohss == "" {
loginType = LoginTypeExistingKubeConfig
} else {
} else if args.ohss != "" {
loginType = LoginTypeJira
} else if args.pd != "" {
loginType = LoginTypePagerduty
}
}
Expand Down Expand Up @@ -606,6 +629,20 @@ func getClusterInfoFromPagerduty(bpConfig config.BackplaneConfiguration) (alert
return alert, nil
}

// getClusterInfoFromJira returns a cluster info OHSS card
func getClusterInfoFromJira() (ohss jira.OHSSIssue, err error) {
if ohssService == nil {
ohssService = jira.NewOHSSService(jira.DefaultIssueService)
}

ohss, err = ohssService.GetIssue(args.ohss)
if err != nil {
return ohss, err
}

return ohss, nil
}

// getClusterIDFromExistingKubeConfig returns clusterId from kubeconfig
func getClusterIDFromExistingKubeConfig() (string, error) {
var clusterKey string
Expand Down
63 changes: 63 additions & 0 deletions cmd/ocm-backplane/login/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/trivago/tgo/tcontainer"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"

"github.com/andygrunwald/go-jira"
"github.com/openshift/backplane-cli/pkg/backplaneapi"
backplaneapiMock "github.com/openshift/backplane-cli/pkg/backplaneapi/mocks"
"github.com/openshift/backplane-cli/pkg/cli/config"
"github.com/openshift/backplane-cli/pkg/client/mocks"
jiraClient "github.com/openshift/backplane-cli/pkg/jira"
jiraMock "github.com/openshift/backplane-cli/pkg/jira/mocks"
"github.com/openshift/backplane-cli/pkg/login"
"github.com/openshift/backplane-cli/pkg/ocm"
ocmMock "github.com/openshift/backplane-cli/pkg/ocm/mocks"
Expand All @@ -40,6 +44,7 @@ var _ = Describe("Login command", func() {
mockClientWithResp *mocks.MockClientWithResponsesInterface
mockOcmInterface *ocmMock.MockOCMInterface
mockClientUtil *backplaneapiMock.MockClientUtils
mockIssueService *jiraMock.MockIssueServiceInterface

testClusterID string
testToken string
Expand Down Expand Up @@ -576,4 +581,62 @@ var _ = Describe("Login command", func() {
})

})

Context("check JIRA OHSS login", func() {
var (
testOHSSID string
testIssue jira.Issue
issueFields *jira.IssueFields
)
BeforeEach(func() {
mockIssueService = jiraMock.NewMockIssueServiceInterface(mockCtrl)
ohssService = jiraClient.NewOHSSService(mockIssueService)
testOHSSID = "OHSS-1000"
})

It("should login to ohss card cluster", func() {

loginType = LoginTypeJira
args.ohss = testOHSSID
err := utils.CreateTempKubeConfig(nil)
args.kubeConfigPath = ""
Expect(err).To(BeNil())
issueFields = &jira.IssueFields{
Project: jira.Project{Key: jiraClient.JiraOHSSProjectKey},
Unknowns: tcontainer.MarshalMap{jiraClient.CustomFieldClusterID: testClusterID},
}
testIssue = jira.Issue{ID: testOHSSID, Fields: issueFields}
globalOpts.ProxyURL = "https://squid.myproxy.com"
mockIssueService.EXPECT().Get(testOHSSID, nil).Return(&testIssue, nil, nil).Times(1)
mockOcmInterface.EXPECT().GetOCMEnvironment().Return(ocmEnv, nil).AnyTimes()
mockClientUtil.EXPECT().SetClientProxyURL(globalOpts.ProxyURL).Return(nil)
mockOcmInterface.EXPECT().GetTargetCluster(testClusterID).Return(testClusterID, testClusterID, nil)
mockOcmInterface.EXPECT().IsClusterHibernating(gomock.Eq(testClusterID)).Return(false, nil).AnyTimes()
mockOcmInterface.EXPECT().GetOCMAccessToken().Return(&testToken, nil)
mockClientUtil.EXPECT().MakeRawBackplaneAPIClientWithAccessToken(backplaneAPIURI, testToken).Return(mockClient, nil)
mockClient.EXPECT().LoginCluster(gomock.Any(), gomock.Eq(testClusterID)).Return(fakeResp, nil)

err = runLogin(nil, nil)

Expect(err).To(BeNil())
})

It("should failed missing cluster id ohss cards", func() {

loginType = LoginTypeJira
args.ohss = testOHSSID

issueFields = &jira.IssueFields{
Project: jira.Project{Key: jiraClient.JiraOHSSProjectKey},
}
testIssue = jira.Issue{ID: testOHSSID, Fields: issueFields}
mockIssueService.EXPECT().Get(testOHSSID, nil).Return(&testIssue, nil, nil).Times(1)
mockOcmInterface.EXPECT().GetOCMEnvironment().Return(ocmEnv, nil).AnyTimes()

err := runLogin(nil, nil)

Expect(err).NotTo(BeNil())
Expect(err.Error()).To(Equal("clusterID cannot be detected for JIRA issue:OHSS-1000"))
})
})
})
11 changes: 6 additions & 5 deletions pkg/accessrequest/accessRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
ocmsdk "github.com/openshift-online/ocm-sdk-go"
acctrspv1 "github.com/openshift-online/ocm-sdk-go/accesstransparency/v1"
"github.com/openshift/backplane-cli/pkg/cli/config"
jiraClient "github.com/openshift/backplane-cli/pkg/jira"
"github.com/openshift/backplane-cli/pkg/ocm"
"github.com/openshift/backplane-cli/pkg/utils"
logger "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -114,7 +115,7 @@ func verifyAndPossiblyRetrieveIssue(bpConfig *config.BackplaneConfiguration, isP
return nil, nil
}

issue, _, err := utils.DefaultIssueService.Get(issueID, nil)
issue, _, err := jiraClient.DefaultIssueService.Get(issueID, nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -145,7 +146,7 @@ func createNotificationIssue(bpConfig *config.BackplaneConfiguration, isProd boo
},
}

issue, _, err := utils.DefaultIssueService.Create(issue)
issue, _, err := jiraClient.DefaultIssueService.Create(issue)
if err != nil {
return nil, err
}
Expand All @@ -164,7 +165,7 @@ func getProjectFromIssueID(issueID string) string {
}

func transitionIssue(issueID, newTransitionName string) {
possibleTransitions, _, err := utils.DefaultIssueService.GetTransitions(issueID)
possibleTransitions, _, err := jiraClient.DefaultIssueService.GetTransitions(issueID)
if err != nil {
logger.Warnf("won't transition the '%s' JIRA issue to '%s' as it was not possible to retrieve the possible transitions for the issue: %v", issueID, newTransitionName, err)
} else {
Expand All @@ -180,7 +181,7 @@ func transitionIssue(issueID, newTransitionName string) {
if transitionID == "" {
logger.Warnf("won't transition the '%s' JIRA issue to '%s' as there is no transition named that way", issueID, newTransitionName)
} else {
_, err := utils.DefaultIssueService.DoTransition(issueID, transitionID)
_, err := jiraClient.DefaultIssueService.DoTransition(issueID, transitionID)

if err != nil {
logger.Warnf("failed to transition the '%s' JIRA issue to '%s': %v", issueID, newTransitionName, err)
Expand All @@ -196,7 +197,7 @@ func updateNotificationIssueDescription(issue *jira.Issue, onApprovalTransitionN
onApprovalTransitionName, accessRequest.HREF()),
}

_, _, err := utils.DefaultIssueService.Update(issue)
_, _, err := jiraClient.DefaultIssueService.Update(issue)
if err != nil {
logger.Warnf("failed to update the description of the '%s' JIRA issue: %v", issue.Key, err)
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/accessrequest/accessRequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (
cmv1 "github.com/openshift-online/ocm-sdk-go/clustersmgmt/v1"
"github.com/openshift/backplane-cli/pkg/backplaneapi"
backplaneapiMock "github.com/openshift/backplane-cli/pkg/backplaneapi/mocks"
jiraClient "github.com/openshift/backplane-cli/pkg/jira"
jiraMocks "github.com/openshift/backplane-cli/pkg/jira/mocks"
"github.com/openshift/backplane-cli/pkg/ocm"
ocmMock "github.com/openshift/backplane-cli/pkg/ocm/mocks"
"github.com/openshift/backplane-cli/pkg/utils"
utilsMocks "github.com/openshift/backplane-cli/pkg/utils/mocks"
)

const testDesc = "accessrequest package"
Expand Down Expand Up @@ -57,7 +57,7 @@ var _ = Describe(testDesc, func() {
mockCtrl *gomock.Controller
mockClientUtil *backplaneapiMock.MockClientUtils
mockOcmInterface *ocmMock.MockOCMInterface
mockIssueService *utilsMocks.MockIssueServiceInterface
mockIssueService *jiraMocks.MockIssueServiceInterface

clusterID string
ocmEnv *cmv1.Environment
Expand All @@ -81,8 +81,8 @@ var _ = Describe(testDesc, func() {
mockOcmInterface = ocmMock.NewMockOCMInterface(mockCtrl)
ocm.DefaultOCMInterface = mockOcmInterface

mockIssueService = utilsMocks.NewMockIssueServiceInterface(mockCtrl)
utils.DefaultIssueService = mockIssueService
mockIssueService = jiraMocks.NewMockIssueServiceInterface(mockCtrl)
jiraClient.DefaultIssueService = mockIssueService

clusterID = "cluster-12345678"

Expand Down
2 changes: 1 addition & 1 deletion pkg/utils/jira.go → pkg/jira/issueService.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package utils
package jira

import (
"errors"
Expand Down
13 changes: 13 additions & 0 deletions pkg/jira/jira_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package jira_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestJira(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Jira Service Suite")
}
2 changes: 1 addition & 1 deletion pkg/utils/mocks/jiraMock.go → pkg/jira/mocks/jiraMock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1699359

Please sign in to comment.