From c2e07b30cd211f5d6a9de8528e8fd1d6e0201a4d Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Tue, 10 Sep 2024 15:54:02 +0100 Subject: [PATCH 1/8] Add support for Broker API In this PR we add support for the Broker API. The Broker API will be used for two calls: - to get Subscription Details, from which we extract the Subscription ID and the Morpheus URL - to exchange the IAM API Client token for Morpheus access and refresh tokens The Morpheus URL and both tokens will then be returned to the calling terraform provider code. The Changes: - we add pkg/models/broker.go to define three structs, two for use with each broker API call and the third returned to the calling terraform provider code - we add pkg/client/broker.go to define the BrokerAPIService which implements GetMorpheusDetails, to make both broker API calls and return the details - we add a boolean removeVmaasCMPBasePath to pkg/client/api.go which is used to toggle removal of VmaasCmpAPIBasePath from the path if true (in the case of the broker API) or include it if false (in the case of the cmp API) - we add two methods to the APIClientHandler interface which will be used in broker client creation by the terraform provider code: - SetMetaFnAndVersion() which will be used to set the meta, tokenFunc and cmpVersion fields in APIClient, this avoids a call to the CMP API to get version information when initialising the Broker Client - GetSCMVersion() to return the CMP version when initialising the Broker Client after the CMP client, we add this as opposed to exporting the existing getVersion() to avoid approx 190 line changes - we add two constants to pkg/common used to set the Broker API paths --- pkg/client/api.go | 14 +++++++-- pkg/client/broker.go | 68 +++++++++++++++++++++++++++++++++++++++++ pkg/client/client.go | 19 ++++++++++-- pkg/common/constants.go | 4 +++ pkg/models/broker.go | 24 +++++++++++++++ 5 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 pkg/client/broker.go create mode 100644 pkg/models/broker.go diff --git a/pkg/client/api.go b/pkg/client/api.go index ef21d67..f8e5ce0 100644 --- a/pkg/client/api.go +++ b/pkg/client/api.go @@ -1,4 +1,4 @@ -// (C) Copyright 2021 Hewlett Packard Enterprise Development LP +// (C) Copyright 2021-2024 Hewlett Packard Enterprise Development LP package client @@ -25,6 +25,8 @@ type api struct { jsonParser jsonPareserFunc validations []validationFunc compatibleVersion string + // removeVmaasCMPBasePath is used to remove the base path of the vmaas-cmp API, for use by the broker API + removeVmaasCMPBasePath bool } // do will call the API provided. this function will not return any response, but @@ -49,7 +51,15 @@ func (a *api) do(ctx context.Context, request interface{}, queryParams map[strin if a.path == "" || a.method == "" || a.client == nil || a.jsonParser == nil { panic("api not properly configured") } - a.path = fmt.Sprintf("%s/%s/%s", a.client.getHost(), consts.VmaasCmpAPIBasePath, a.path) + + // Set the path + if !a.removeVmaasCMPBasePath { + // Add the base path of the vmaas-cmp API if we are calling the vmaas-cmp API + a.path = fmt.Sprintf("%s/%s/%s", a.client.getHost(), consts.VmaasCmpAPIBasePath, a.path) + } else { + // Don't use the base path of the vmaas-cmp API if we are calling the broker API + a.path = fmt.Sprintf("%s/%s", a.client.getHost(), a.path) + } for _, validations := range a.validations { err := validations() diff --git a/pkg/client/broker.go b/pkg/client/broker.go new file mode 100644 index 0000000..8730d6a --- /dev/null +++ b/pkg/client/broker.go @@ -0,0 +1,68 @@ +// (C) Copyright 2024 Hewlett Packard Enterprise Development LP + +package client + +import ( + "context" + "encoding/json" + "fmt" + "log" + + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" + "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" +) + +// BrokerAPIService is a service that provides methods to interact with the broker API +type BrokerAPIService struct { + Client APIClientHandler + Cfg Configuration +} + +// GetMorpheusDetails returns Morpheus details to terraform +func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.MorpheusDetails, error) { + // Get the service instance ID and Morpheus URL + ServiceSubscriptionDetailsResp := models.SubscriptionDetailsResponse{} + serviceSubscriptionDetailsAPI := &api{ + method: "GET", + path: consts.SubscriptionDetails, + client: a.Client, + removeVmaasCMPBasePath: true, + + jsonParser: func(body []byte) error { + return json.Unmarshal(body, &ServiceSubscriptionDetailsResp) + }, + } + + // Use the default query params + if err := serviceSubscriptionDetailsAPI.do(ctx, nil, a.Cfg.DefaultQueryParams); err != nil { + return models.MorpheusDetails{}, fmt.Errorf("error getting service subscription details: %v", err) + } + + // Get the Morpheus token + MorpheusTokenResp := models.MorpheusTokenResponse{} + log.Printf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID) + morpheusTokenAPI := &api{ + method: "GET", + path: fmt.Sprintf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID), + client: a.Client, + removeVmaasCMPBasePath: true, + + jsonParser: func(body []byte) error { + return json.Unmarshal(body, &MorpheusTokenResp) + }, + } + + // No query params needed + if err := morpheusTokenAPI.do(ctx, nil, nil); err != nil { + return models.MorpheusDetails{}, fmt.Errorf("error getting Morpheus token: %v", err) + } + + // build response + ret := models.MorpheusDetails{ + AccessToken: MorpheusTokenResp.AccessToken, + RefreshToken: MorpheusTokenResp.RefreshToken, + URL: ServiceSubscriptionDetailsResp.URL, + } + + return ret, nil +} diff --git a/pkg/client/client.go b/pkg/client/client.go index 7e5a514..89c6d1f 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1,4 +1,4 @@ -// (C) Copyright 2021 Hewlett Packard Enterprise Development LP +// (C) Copyright 2021-2024 Hewlett Packard Enterprise Development LP //go:generate go run github.com/golang/mock/mockgen -source ./client.go -package client -destination ./client_mock.go @@ -36,6 +36,11 @@ type APIClientHandler interface { SetMeta(meta interface{}, fn SetScmClientToken) error getVersion() int getHost() string + // The next two methods are for use when creating the Broker API client + // SetMetaFnAndVersion is used to set the client token function in meta and the SCM version for the Broker client + SetMetaFnAndVersion(meta interface{}, version int, fn SetScmClientToken) + // GetSCMVersion returns the SCM version for use when creating the Broker client + GetSCMVersion() int } // APIClient manages communication with the GreenLake Private Cloud VMaaS CMP API API v1.0.0 @@ -96,6 +101,12 @@ func (c *APIClient) SetMeta(meta interface{}, fn SetScmClientToken) error { return nil } +func (c *APIClient) SetMetaFnAndVersion(meta interface{}, version int, fn SetScmClientToken) { + c.meta = meta + c.tokenFunc = fn + c.cmpVersion = version +} + // callAPI do the request. func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { return c.cfg.HTTPClient.Do(request) @@ -110,8 +121,12 @@ func (c *APIClient) getVersion() int { return c.cmpVersion } +func (c *APIClient) GetSCMVersion() int { + return c.cmpVersion +} + // prepareRequest build the request -//nolint +// nolint func (c *APIClient) prepareRequest( ctx context.Context, path string, method string, diff --git a/pkg/common/constants.go b/pkg/common/constants.go index 84df06a..c09e85e 100644 --- a/pkg/common/constants.go +++ b/pkg/common/constants.go @@ -69,4 +69,8 @@ const ( // Morpheus version CMPSixZeroFiveVersion = "6.0.5" + + // Broker API paths + SubscriptionDetails = "vmaas/api/v1alpha1/subscription_details" + MorpheusToken = "vmaas/api/v1/service_instances/%s/cmp_access_token" ) diff --git a/pkg/models/broker.go b/pkg/models/broker.go new file mode 100644 index 0000000..248d4f6 --- /dev/null +++ b/pkg/models/broker.go @@ -0,0 +1,24 @@ +// (C) Copyright 2024 Hewlett Packard Enterprise Development LP + +package models + +// Broker structs go here + +// SubscriptionDetailsResponse is the response for Subscription Details from the broker +type SubscriptionDetailsResponse struct { + ServiceInstanceID string `json:"ServiceInstanceID"` + URL string `json:"URL"` +} + +// MorpheusTokenResponse is the response for Morpheus Token from the broker +type MorpheusTokenResponse struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` +} + +// MorpheusDetails is what we return to terraform +type MorpheusDetails struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + URL string `json:"URL"` +} From 1aee1b3c0576f87c6bd4d34fea2122c454e2c57e Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Thu, 12 Sep 2024 09:53:33 +0100 Subject: [PATCH 2/8] Gandharva's changes --- pkg/client/broker.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/client/broker.go b/pkg/client/broker.go index 8730d6a..c08d343 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "log" + "net/http" consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" @@ -23,7 +24,7 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // Get the service instance ID and Morpheus URL ServiceSubscriptionDetailsResp := models.SubscriptionDetailsResponse{} serviceSubscriptionDetailsAPI := &api{ - method: "GET", + method: http.MethodGet, path: consts.SubscriptionDetails, client: a.Client, removeVmaasCMPBasePath: true, @@ -42,7 +43,7 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph MorpheusTokenResp := models.MorpheusTokenResponse{} log.Printf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID) morpheusTokenAPI := &api{ - method: "GET", + method: http.MethodGet, path: fmt.Sprintf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID), client: a.Client, removeVmaasCMPBasePath: true, From 9c9d2cec54bed2d3073d614568b02fc181d4edb1 Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Mon, 16 Sep 2024 15:22:44 +0100 Subject: [PATCH 3/8] Add broker unit tests and remove debug statement Signed-off-by: Eamonn O'Toole --- pkg/client/broker.go | 2 - pkg/client/broker_test.go | 254 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 pkg/client/broker_test.go diff --git a/pkg/client/broker.go b/pkg/client/broker.go index c08d343..b1e881f 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -6,7 +6,6 @@ import ( "context" "encoding/json" "fmt" - "log" "net/http" consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" @@ -41,7 +40,6 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // Get the Morpheus token MorpheusTokenResp := models.MorpheusTokenResponse{} - log.Printf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID) morpheusTokenAPI := &api{ method: http.MethodGet, path: fmt.Sprintf(consts.MorpheusToken, ServiceSubscriptionDetailsResp.ServiceInstanceID), diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go new file mode 100644 index 0000000..2a867a2 --- /dev/null +++ b/pkg/client/broker_test.go @@ -0,0 +1,254 @@ +// (C) Copyright 2024 Hewlett Packard Enterprise Development LP + +package client + +import ( + "bytes" + "context" + "errors" + "fmt" + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" + "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" + "io" + "net/http" + "net/url" + "testing" + + "github.com/golang/mock/gomock" +) + +const ( + testTenantID = "1234" + testBrokerURL = "https://broker.com" + testSubscriptionID = "18ba6409-ac59-4eac-9414-0147e72d615e" + testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" +) + +func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { + ctx := context.Background() + testCtrl := gomock.NewController(t) + defer testCtrl.Finish() + + headers := getDefaultHeaders() + // headers["X-Tenant-ID"] = testTenantID + + queryParams := map[string]string{ + "location": "BLR", + "space_name": "default", + } + + clientCfg := Configuration{ + DefaultHeader: headers, + DefaultQueryParams: queryParams, + } + + tests := []struct { + name string + given func(m *MockAPIClientHandler) + want models.MorpheusDetails + wantErr bool + }{ + { + name: "Test GetMorpheusDetails success", + want: models.MorpheusDetails{ + AccessToken: testAccessToken, + RefreshToken: testRefreshToken, + URL: testMorpheusURL, + }, + wantErr: false, + given: func(m *MockAPIClientHandler) { + // Get subscription details + m.EXPECT().getHost().Return(mockHost) + pathSubscription := mockHost + "/" + consts.SubscriptionDetails + method := "GET" + reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) + respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` + { + "ServiceInstanceID": "` + testSubscriptionID + `", + "URL": "` + testMorpheusURL + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathSubscription, method, nil, headers, + getURLValues(queryParams), url.Values{}, "", nil).Return(reqSubscription, nil) + + m.EXPECT().callAPI(reqSubscription).Return(&http.Response{ + StatusCode: 200, + Body: respBodySubscription, + }, nil) + + // Get Morpheus token + m.EXPECT().getHost().Return(mockHost) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + reqToken, _ := http.NewRequest(method, pathToken, nil) + respBodyToken := io.NopCloser(bytes.NewReader([]byte(` + { + "access_token": "` + testAccessToken + `", + "refresh_token": "` + testRefreshToken + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, + url.Values{}, url.Values{}, "", nil).Return(reqToken, nil) + + m.EXPECT().callAPI(reqToken).Return(&http.Response{ + StatusCode: 200, + Body: respBodyToken, + }, nil) + }, + }, + + { + name: "Test GetMorpheusDetails error in get subscription details prepare request", + want: models.MorpheusDetails{}, + wantErr: true, + given: func(m *MockAPIClientHandler) { + // Get subscription details + m.EXPECT().getHost().Return(mockHost) + pathSubscription := mockHost + "/" + consts.SubscriptionDetails + method := "GET" + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathSubscription, method, nil, headers, + getURLValues(queryParams), url.Values{}, "", nil). + Return(nil, errors.New("error in prepare request")) + }, + }, + + { + name: "Test GetMorpheusDetails error in get subscription details call API", + want: models.MorpheusDetails{}, + wantErr: true, + given: func(m *MockAPIClientHandler) { + // Get subscription details + m.EXPECT().getHost().Return(mockHost) + pathSubscription := mockHost + "/" + consts.SubscriptionDetails + method := "GET" + reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) + respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` + { + "ServiceInstanceID": "` + testSubscriptionID + `", + "URL": "` + testMorpheusURL + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathSubscription, method, nil, headers, + getURLValues(queryParams), url.Values{}, "", nil).Return(reqSubscription, nil) + + m.EXPECT().callAPI(reqSubscription).Return(&http.Response{ + StatusCode: 500, + Body: respBodySubscription, + }, nil) + }, + }, + + { + name: "Test GetMorpheusDetails error in get Morpheus token prepare request", + want: models.MorpheusDetails{}, + wantErr: true, + given: func(m *MockAPIClientHandler) { + // Get subscription details + m.EXPECT().getHost().Return(mockHost) + pathSubscription := mockHost + "/" + consts.SubscriptionDetails + method := "GET" + reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) + respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` + { + "ServiceInstanceID": "` + testSubscriptionID + `", + "URL": "` + testMorpheusURL + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathSubscription, method, nil, headers, + getURLValues(queryParams), url.Values{}, "", nil).Return(reqSubscription, nil) + + m.EXPECT().callAPI(reqSubscription).Return(&http.Response{ + StatusCode: 200, + Body: respBodySubscription, + }, nil) + + // Get Morpheus token + m.EXPECT().getHost().Return(mockHost) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, + url.Values{}, url.Values{}, "", nil). + Return(nil, errors.New("error in prepare request")) + }, + }, + + { + name: "Test GetMorpheusDetails error in get Morpheus token call API", + want: models.MorpheusDetails{}, + wantErr: true, + given: func(m *MockAPIClientHandler) { + // Get subscription details + m.EXPECT().getHost().Return(mockHost) + pathSubscription := mockHost + "/" + consts.SubscriptionDetails + method := "GET" + reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) + respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` + { + "ServiceInstanceID": "` + testSubscriptionID + `", + "URL": "` + testMorpheusURL + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathSubscription, method, nil, headers, + getURLValues(queryParams), url.Values{}, "", nil).Return(reqSubscription, nil) + + m.EXPECT().callAPI(reqSubscription).Return(&http.Response{ + StatusCode: 200, + Body: respBodySubscription, + }, nil) + + // Get Morpheus token + m.EXPECT().getHost().Return(mockHost) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + reqToken, _ := http.NewRequest(method, pathToken, nil) + respBodyToken := io.NopCloser(bytes.NewReader([]byte(` + { + "access_token": "` + testAccessToken + `", + "refresh_token": "` + testRefreshToken + `" + } + `))) + // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) + m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, + url.Values{}, url.Values{}, "", nil).Return(reqToken, nil) + + m.EXPECT().callAPI(reqToken).Return(&http.Response{ + StatusCode: 500, + Body: respBodyToken, + }, nil) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockClient := NewMockAPIClientHandler(testCtrl) + tt.given(mockClient) + a := &BrokerAPIService{ + Cfg: clientCfg, + Client: mockClient, + } + got, err := a.GetMorpheusDetails(ctx) + if (err != nil) != tt.wantErr { + t.Errorf("BrokerAPIService.GetMorpheusDetails() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("BrokerAPIService.GetMorpheusDetails() = %v, want %v", got, tt.want) + } + }) + } +} From 8c757072e87ab3184db74dc0923e3f3fd6d76751 Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Mon, 16 Sep 2024 15:24:48 +0100 Subject: [PATCH 4/8] Tidy up broker unit-tests --- pkg/client/broker_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go index 2a867a2..af52ba5 100644 --- a/pkg/client/broker_test.go +++ b/pkg/client/broker_test.go @@ -7,19 +7,18 @@ import ( "context" "errors" "fmt" - consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" - "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" "io" "net/http" "net/url" "testing" "github.com/golang/mock/gomock" + + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" + "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" ) const ( - testTenantID = "1234" - testBrokerURL = "https://broker.com" testSubscriptionID = "18ba6409-ac59-4eac-9414-0147e72d615e" testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" @@ -32,7 +31,6 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { defer testCtrl.Finish() headers := getDefaultHeaders() - // headers["X-Tenant-ID"] = testTenantID queryParams := map[string]string{ "location": "BLR", From 7ab9536f10e99e36db6a0009ccbaf481c0f494ca Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Mon, 16 Sep 2024 17:02:26 +0100 Subject: [PATCH 5/8] Add some more details to MorpheusDetails In this commit we add: - access_token_expires_in - refresh_token_expires --- go.mod | 4 +++ go.sum | 10 ++++++++ pkg/client/broker.go | 8 +++--- pkg/client/broker_test.go | 51 ++++++++++++++++++++++++--------------- pkg/models/broker.go | 14 +++++++---- 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 9643257..a035c1f 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,15 @@ go 1.21 require ( github.com/antihax/optional v1.0.0 github.com/golang/mock v1.6.0 + github.com/stretchr/testify v1.9.0 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/mod v0.4.2 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/tools v0.1.4 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3762b4f..2ded73e 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,13 @@ github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -31,3 +37,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/client/broker.go b/pkg/client/broker.go index b1e881f..781e7fb 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -58,9 +58,11 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // build response ret := models.MorpheusDetails{ - AccessToken: MorpheusTokenResp.AccessToken, - RefreshToken: MorpheusTokenResp.RefreshToken, - URL: ServiceSubscriptionDetailsResp.URL, + AccessToken: MorpheusTokenResp.AccessToken, + RefreshToken: MorpheusTokenResp.RefreshToken, + AccessTokenExpiresIn: MorpheusTokenResp.AccessTokenExpiresIn, + RefreshTokenExpires: MorpheusTokenResp.RefreshTokenExpires, + URL: ServiceSubscriptionDetailsResp.URL, } return ret, nil diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go index af52ba5..0644c5c 100644 --- a/pkg/client/broker_test.go +++ b/pkg/client/broker_test.go @@ -5,6 +5,7 @@ package client import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" @@ -14,15 +15,19 @@ import ( "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" ) const ( - testSubscriptionID = "18ba6409-ac59-4eac-9414-0147e72d615e" - testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" - testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" - testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" + testSubscriptionID = "18ba6409-ac59-4eac-9414-0147e72d615e" + testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" + testAccessTokenExpiresIn = 3600 + testRefreshTokenExpires = 1758034360176 ) func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { @@ -51,9 +56,11 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails success", want: models.MorpheusDetails{ - AccessToken: testAccessToken, - RefreshToken: testRefreshToken, - URL: testMorpheusURL, + AccessToken: testAccessToken, + RefreshToken: testRefreshToken, + AccessTokenExpiresIn: testAccessTokenExpiresIn, + RefreshTokenExpires: testRefreshTokenExpires, + URL: testMorpheusURL, }, wantErr: false, given: func(m *MockAPIClientHandler) { @@ -82,12 +89,15 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { m.EXPECT().getHost().Return(mockHost) pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) reqToken, _ := http.NewRequest(method, pathToken, nil) - respBodyToken := io.NopCloser(bytes.NewReader([]byte(` - { - "access_token": "` + testAccessToken + `", - "refresh_token": "` + testRefreshToken + `" - } - `))) + tokenResp := models.MorpheusTokenResponse{ + AccessToken: testAccessToken, + RefreshToken: testRefreshToken, + AccessTokenExpiresIn: testAccessTokenExpiresIn, + RefreshTokenExpires: testRefreshTokenExpires, + } + body, err := json.Marshal(tokenResp) + assert.NoError(t, err) + respBodyToken := io.NopCloser(bytes.NewReader(body)) // mock the context only since it is not validated in this function m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, @@ -212,12 +222,15 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { m.EXPECT().getHost().Return(mockHost) pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) reqToken, _ := http.NewRequest(method, pathToken, nil) - respBodyToken := io.NopCloser(bytes.NewReader([]byte(` - { - "access_token": "` + testAccessToken + `", - "refresh_token": "` + testRefreshToken + `" - } - `))) + tokenResp := models.MorpheusTokenResponse{ + AccessToken: testAccessToken, + RefreshToken: testRefreshToken, + AccessTokenExpiresIn: testAccessTokenExpiresIn, + RefreshTokenExpires: testRefreshTokenExpires, + } + body, err := json.Marshal(tokenResp) + assert.NoError(t, err) + respBodyToken := io.NopCloser(bytes.NewReader([]byte(body))) // mock the context only since it is not validated in this function m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, diff --git a/pkg/models/broker.go b/pkg/models/broker.go index 248d4f6..8298fd5 100644 --- a/pkg/models/broker.go +++ b/pkg/models/broker.go @@ -12,13 +12,17 @@ type SubscriptionDetailsResponse struct { // MorpheusTokenResponse is the response for Morpheus Token from the broker type MorpheusTokenResponse struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + AccessTokenExpiresIn int `json:"expires_in"` + RefreshTokenExpires int `json:"expires"` } // MorpheusDetails is what we return to terraform type MorpheusDetails struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - URL string `json:"URL"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + AccessTokenExpiresIn int `json:"access_token_expires_in"` + RefreshTokenExpires int `json:"refresh_token_expires"` + URL string `json:"URL"` } From befa85fdbc5c2fbcb153320bff14841afe862d3b Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Mon, 16 Sep 2024 17:36:13 +0100 Subject: [PATCH 6/8] Adding ServiceInstanceID to MorpheusDetails This is for use by the provider code. --- pkg/client/broker.go | 1 + pkg/client/broker_test.go | 17 +++++++++-------- pkg/models/broker.go | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pkg/client/broker.go b/pkg/client/broker.go index 781e7fb..8ff0f85 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -58,6 +58,7 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // build response ret := models.MorpheusDetails{ + ID: ServiceSubscriptionDetailsResp.ServiceInstanceID, AccessToken: MorpheusTokenResp.AccessToken, RefreshToken: MorpheusTokenResp.RefreshToken, AccessTokenExpiresIn: MorpheusTokenResp.AccessTokenExpiresIn, diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go index 0644c5c..fac4a8c 100644 --- a/pkg/client/broker_test.go +++ b/pkg/client/broker_test.go @@ -22,7 +22,7 @@ import ( ) const ( - testSubscriptionID = "18ba6409-ac59-4eac-9414-0147e72d615e" + testServiceInstanceID = "18ba6409-ac59-4eac-9414-0147e72d615e" testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" @@ -56,6 +56,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails success", want: models.MorpheusDetails{ + ID: testServiceInstanceID, AccessToken: testAccessToken, RefreshToken: testRefreshToken, AccessTokenExpiresIn: testAccessTokenExpiresIn, @@ -71,7 +72,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` { - "ServiceInstanceID": "` + testSubscriptionID + `", + "ServiceInstanceID": "` + testServiceInstanceID + `", "URL": "` + testMorpheusURL + `" } `))) @@ -87,7 +88,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { // Get Morpheus token m.EXPECT().getHost().Return(mockHost) - pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ AccessToken: testAccessToken, @@ -139,7 +140,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` { - "ServiceInstanceID": "` + testSubscriptionID + `", + "ServiceInstanceID": "` + testServiceInstanceID + `", "URL": "` + testMorpheusURL + `" } `))) @@ -167,7 +168,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` { - "ServiceInstanceID": "` + testSubscriptionID + `", + "ServiceInstanceID": "` + testServiceInstanceID + `", "URL": "` + testMorpheusURL + `" } `))) @@ -183,7 +184,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { // Get Morpheus token m.EXPECT().getHost().Return(mockHost) - pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) // mock the context only since it is not validated in this function m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), pathToken, method, nil, headers, @@ -204,7 +205,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { reqSubscription, _ := http.NewRequest(method, pathSubscription, nil) respBodySubscription := io.NopCloser(bytes.NewReader([]byte(` { - "ServiceInstanceID": "` + testSubscriptionID + `", + "ServiceInstanceID": "` + testServiceInstanceID + `", "URL": "` + testMorpheusURL + `" } `))) @@ -220,7 +221,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { // Get Morpheus token m.EXPECT().getHost().Return(mockHost) - pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testSubscriptionID) + pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ AccessToken: testAccessToken, diff --git a/pkg/models/broker.go b/pkg/models/broker.go index 8298fd5..fca7869 100644 --- a/pkg/models/broker.go +++ b/pkg/models/broker.go @@ -20,6 +20,7 @@ type MorpheusTokenResponse struct { // MorpheusDetails is what we return to terraform type MorpheusDetails struct { + ID string `json:"id"` // This is the ServiceInstanceID, added here for use by the provider AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` AccessTokenExpiresIn int `json:"access_token_expires_in"` From c6c630e6083e072ff11a2d593cd75eea63477fe7 Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Tue, 17 Sep 2024 16:03:23 +0100 Subject: [PATCH 7/8] Clean-up of MorpheusDetails and MorpheusTokenResponse We only add access_token and expires to MorpheusTokenResponse and MorpheusDetails. --- pkg/client/broker.go | 10 ++++------ pkg/client/broker_test.go | 32 ++++++++++++-------------------- pkg/models/broker.go | 16 ++++++---------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/pkg/client/broker.go b/pkg/client/broker.go index 8ff0f85..9fe2abc 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -58,12 +58,10 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // build response ret := models.MorpheusDetails{ - ID: ServiceSubscriptionDetailsResp.ServiceInstanceID, - AccessToken: MorpheusTokenResp.AccessToken, - RefreshToken: MorpheusTokenResp.RefreshToken, - AccessTokenExpiresIn: MorpheusTokenResp.AccessTokenExpiresIn, - RefreshTokenExpires: MorpheusTokenResp.RefreshTokenExpires, - URL: ServiceSubscriptionDetailsResp.URL, + ID: ServiceSubscriptionDetailsResp.ServiceInstanceID, + AccessToken: MorpheusTokenResp.AccessToken, + AccessTokenExpires: MorpheusTokenResp.AccessTokenExpires, + URL: ServiceSubscriptionDetailsResp.URL, } return ret, nil diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go index fac4a8c..3405f21 100644 --- a/pkg/client/broker_test.go +++ b/pkg/client/broker_test.go @@ -22,12 +22,10 @@ import ( ) const ( - testServiceInstanceID = "18ba6409-ac59-4eac-9414-0147e72d615e" - testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" - testRefreshToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" - testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" - testAccessTokenExpiresIn = 3600 - testRefreshTokenExpires = 1758034360176 + testServiceInstanceID = "18ba6409-ac59-4eac-9414-0147e72d615e" + testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" + testAccessTokenExpires = 1758034360176 ) func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { @@ -56,12 +54,10 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails success", want: models.MorpheusDetails{ - ID: testServiceInstanceID, - AccessToken: testAccessToken, - RefreshToken: testRefreshToken, - AccessTokenExpiresIn: testAccessTokenExpiresIn, - RefreshTokenExpires: testRefreshTokenExpires, - URL: testMorpheusURL, + ID: testServiceInstanceID, + AccessToken: testAccessToken, + AccessTokenExpires: testAccessTokenExpires, + URL: testMorpheusURL, }, wantErr: false, given: func(m *MockAPIClientHandler) { @@ -91,10 +87,8 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ - AccessToken: testAccessToken, - RefreshToken: testRefreshToken, - AccessTokenExpiresIn: testAccessTokenExpiresIn, - RefreshTokenExpires: testRefreshTokenExpires, + AccessToken: testAccessToken, + AccessTokenExpires: testAccessTokenExpires, } body, err := json.Marshal(tokenResp) assert.NoError(t, err) @@ -224,10 +218,8 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ - AccessToken: testAccessToken, - RefreshToken: testRefreshToken, - AccessTokenExpiresIn: testAccessTokenExpiresIn, - RefreshTokenExpires: testRefreshTokenExpires, + AccessToken: testAccessToken, + AccessTokenExpires: testAccessTokenExpires, } body, err := json.Marshal(tokenResp) assert.NoError(t, err) diff --git a/pkg/models/broker.go b/pkg/models/broker.go index fca7869..75537da 100644 --- a/pkg/models/broker.go +++ b/pkg/models/broker.go @@ -12,18 +12,14 @@ type SubscriptionDetailsResponse struct { // MorpheusTokenResponse is the response for Morpheus Token from the broker type MorpheusTokenResponse struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - AccessTokenExpiresIn int `json:"expires_in"` - RefreshTokenExpires int `json:"expires"` + AccessToken string `json:"access_token"` + AccessTokenExpires int `json:"expires"` } // MorpheusDetails is what we return to terraform type MorpheusDetails struct { - ID string `json:"id"` // This is the ServiceInstanceID, added here for use by the provider - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - AccessTokenExpiresIn int `json:"access_token_expires_in"` - RefreshTokenExpires int `json:"refresh_token_expires"` - URL string `json:"URL"` + ID string `json:"id"` // This is the ServiceInstanceID, added here for use by the provider + AccessToken string `json:"access_token"` + AccessTokenExpires int `json:"access_token_expires"` // This is the Unix timestamp of when the token expires + URL string `json:"URL"` } From 56de964e299201a18695a8a9f2dab178a0dbe609 Mon Sep 17 00:00:00 2001 From: Eamonn O'Toole Date: Wed, 18 Sep 2024 10:45:35 +0100 Subject: [PATCH 8/8] More changes requested by Mahesh. --- pkg/client/broker.go | 16 +++++++-------- pkg/client/broker_test.go | 42 ++++++++++++++++++++++----------------- pkg/models/broker.go | 20 +++++++++++-------- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/pkg/client/broker.go b/pkg/client/broker.go index 9fe2abc..84c1804 100644 --- a/pkg/client/broker.go +++ b/pkg/client/broker.go @@ -19,7 +19,7 @@ type BrokerAPIService struct { } // GetMorpheusDetails returns Morpheus details to terraform -func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.MorpheusDetails, error) { +func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.TFMorpheusDetails, error) { // Get the service instance ID and Morpheus URL ServiceSubscriptionDetailsResp := models.SubscriptionDetailsResponse{} serviceSubscriptionDetailsAPI := &api{ @@ -35,7 +35,7 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // Use the default query params if err := serviceSubscriptionDetailsAPI.do(ctx, nil, a.Cfg.DefaultQueryParams); err != nil { - return models.MorpheusDetails{}, fmt.Errorf("error getting service subscription details: %v", err) + return models.TFMorpheusDetails{}, fmt.Errorf("error getting service subscription details: %v", err) } // Get the Morpheus token @@ -53,15 +53,15 @@ func (a *BrokerAPIService) GetMorpheusDetails(ctx context.Context) (models.Morph // No query params needed if err := morpheusTokenAPI.do(ctx, nil, nil); err != nil { - return models.MorpheusDetails{}, fmt.Errorf("error getting Morpheus token: %v", err) + return models.TFMorpheusDetails{}, fmt.Errorf("error getting Morpheus token: %v", err) } // build response - ret := models.MorpheusDetails{ - ID: ServiceSubscriptionDetailsResp.ServiceInstanceID, - AccessToken: MorpheusTokenResp.AccessToken, - AccessTokenExpires: MorpheusTokenResp.AccessTokenExpires, - URL: ServiceSubscriptionDetailsResp.URL, + ret := models.TFMorpheusDetails{ + ID: ServiceSubscriptionDetailsResp.ServiceInstanceID, + AccessToken: MorpheusTokenResp.AccessToken, + ValidTill: MorpheusTokenResp.Expires, + URL: ServiceSubscriptionDetailsResp.URL, } return ret, nil diff --git a/pkg/client/broker_test.go b/pkg/client/broker_test.go index 3405f21..010469d 100644 --- a/pkg/client/broker_test.go +++ b/pkg/client/broker_test.go @@ -22,10 +22,12 @@ import ( ) const ( - testServiceInstanceID = "18ba6409-ac59-4eac-9414-0147e72d615e" - testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" - testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" - testAccessTokenExpires = 1758034360176 + testServiceInstanceID = "18ba6409-ac59-4eac-9414-0147e72d615e" + testAccessToken = "2b9fba7f-7c14-4773-a970-a9ad393811ac" + testRefreshToken = "7806acfb-f847-48b1-a6d5-6119dccb3ffe" + testMorpheusURL = "https://1234-mp.private.greenlake.hpe-gl-intg.com/" + testAccessTokenExpires = 1758034360176 + testAccessTokenExpiresIn = 3600 ) func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { @@ -48,16 +50,16 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { tests := []struct { name string given func(m *MockAPIClientHandler) - want models.MorpheusDetails + want models.TFMorpheusDetails wantErr bool }{ { name: "Test GetMorpheusDetails success", - want: models.MorpheusDetails{ - ID: testServiceInstanceID, - AccessToken: testAccessToken, - AccessTokenExpires: testAccessTokenExpires, - URL: testMorpheusURL, + want: models.TFMorpheusDetails{ + ID: testServiceInstanceID, + AccessToken: testAccessToken, + ValidTill: testAccessTokenExpires, + URL: testMorpheusURL, }, wantErr: false, given: func(m *MockAPIClientHandler) { @@ -87,8 +89,10 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ - AccessToken: testAccessToken, - AccessTokenExpires: testAccessTokenExpires, + AccessToken: testAccessToken, + Expires: testAccessTokenExpires, + RefreshToken: testRefreshToken, + ExpiresIn: testAccessTokenExpiresIn, } body, err := json.Marshal(tokenResp) assert.NoError(t, err) @@ -107,7 +111,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails error in get subscription details prepare request", - want: models.MorpheusDetails{}, + want: models.TFMorpheusDetails{}, wantErr: true, given: func(m *MockAPIClientHandler) { // Get subscription details @@ -124,7 +128,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails error in get subscription details call API", - want: models.MorpheusDetails{}, + want: models.TFMorpheusDetails{}, wantErr: true, given: func(m *MockAPIClientHandler) { // Get subscription details @@ -152,7 +156,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails error in get Morpheus token prepare request", - want: models.MorpheusDetails{}, + want: models.TFMorpheusDetails{}, wantErr: true, given: func(m *MockAPIClientHandler) { // Get subscription details @@ -189,7 +193,7 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { { name: "Test GetMorpheusDetails error in get Morpheus token call API", - want: models.MorpheusDetails{}, + want: models.TFMorpheusDetails{}, wantErr: true, given: func(m *MockAPIClientHandler) { // Get subscription details @@ -218,8 +222,10 @@ func TestBrokerAPIService_GetMorpheusDetails(t *testing.T) { pathToken := mockHost + "/" + fmt.Sprintf(consts.MorpheusToken, testServiceInstanceID) reqToken, _ := http.NewRequest(method, pathToken, nil) tokenResp := models.MorpheusTokenResponse{ - AccessToken: testAccessToken, - AccessTokenExpires: testAccessTokenExpires, + AccessToken: testAccessToken, + Expires: testAccessTokenExpires, + RefreshToken: testRefreshToken, + ExpiresIn: testAccessTokenExpiresIn, } body, err := json.Marshal(tokenResp) assert.NoError(t, err) diff --git a/pkg/models/broker.go b/pkg/models/broker.go index 75537da..3cdae0e 100644 --- a/pkg/models/broker.go +++ b/pkg/models/broker.go @@ -12,14 +12,18 @@ type SubscriptionDetailsResponse struct { // MorpheusTokenResponse is the response for Morpheus Token from the broker type MorpheusTokenResponse struct { - AccessToken string `json:"access_token"` - AccessTokenExpires int `json:"expires"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + Expires int64 `json:"expires"` + ExpiresIn int64 `json:"expires_in"` } -// MorpheusDetails is what we return to terraform -type MorpheusDetails struct { - ID string `json:"id"` // This is the ServiceInstanceID, added here for use by the provider - AccessToken string `json:"access_token"` - AccessTokenExpires int `json:"access_token_expires"` // This is the Unix timestamp of when the token expires - URL string `json:"URL"` +// TFMorpheusDetails is what we return to terraform +type TFMorpheusDetails struct { + // ID is the ServiceInstanceID, added here for use by the provider when storing the data + ID string `json:"id"` + AccessToken string `json:"access_token"` + // ValidTill Unix timestamp of when the access_token expires in seconds + ValidTill int64 `json:"valid_till"` + URL string `json:"URL"` }