diff --git a/pkg/client/api.go b/pkg/client/api.go index a833c2a..6c2f8b6 100644 --- a/pkg/client/api.go +++ b/pkg/client/api.go @@ -4,6 +4,7 @@ package client import ( "context" + "fmt" "io/ioutil" "net/url" "strings" @@ -18,16 +19,28 @@ type validationFunc func() error type jsonPareserFunc func(body []byte) error type api struct { - method string - path string - client APIClientHandler - jsonParser jsonPareserFunc - validations []validationFunc + method string + path string + client APIClientHandler + jsonParser jsonPareserFunc + validations []validationFunc + compatibleVersion string } // do will call the API provided. this function will not return any response, but // response should be catched from jsonParser function itself func (a *api) do(ctx context.Context, request interface{}, queryParams map[string]string) error { + currentVersion, err := parseVersion(a.compatibleVersion) + if err != nil { + panic(fmt.Sprintf("failed to parse the current version, error: %v", err)) + } + if a.client.getVersion() < currentVersion { + if a.client.getVersion() == 0 { + return fmt.Errorf("failed to get meta data for cmp-sdk") + } + + return errVersion + } var ( localVarHTTPMethod = strings.ToUpper(a.method) localVarFileName string diff --git a/pkg/client/client.go b/pkg/client/client.go index 9261c78..cb6ba08 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -11,22 +11,14 @@ import ( "encoding/xml" "errors" "fmt" - "io" "mime/multipart" "net/http" "net/url" - "os" "path/filepath" - "reflect" - "regexp" "strings" - "time" ) -var ( - jsonCheck = regexp.MustCompile("(?i:[application|text]/json)") - xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)") -) +type SetScmClientToken func(ctx *context.Context, meta interface{}) type APIClientHandler interface { ChangeBasePath(path string) @@ -41,38 +33,22 @@ type APIClientHandler interface { fileBytes []byte) (localVarRequest *http.Request, err error) decode(v interface{}, b []byte, contentType string) (err error) callAPI(request *http.Request) (*http.Response, error) + SetMeta(meta interface{}, fn SetScmClientToken) error + getVersion() int } // APIClient manages communication with the GreenLake Private Cloud VMaaS CMP API API v1.0.0 // In most cases there should be only one, shared, APIClient. type APIClient struct { - cfg *Configuration - common service // Reuse a single struct instead of allocating one for each service on the heap. - - // API Services - - /*CloudsAPI *CloudsAPIService - - GroupsAPI *GroupsAPIService - - InstancesAPI *InstancesAPIService - - KeysCertsAPI *KeysCertsAPIService - - LibraryAPI *LibraryAPIService - - NetworksAPI *NetworksAPIService - - PlansAPI *PlansAPIService - - PoliciesAPI *PoliciesAPIService - - RolesAPI *RolesAPIService*/ + cfg *Configuration + cmpVersion int + meta interface{} + tokenFunc SetScmClientToken } -type service struct { - client *APIClient -} +// defaultTokenFunc will use while defining httpClient. defaultTokenFunc +// will not fetch any token or update context. +func defaultTokenFunc(ctx *context.Context, meta interface{}) {} // NewAPIClient creates a new API Client. Requires a userAgent string describing your application. // optionally a custom http.Client to allow for advanced features such as caching. @@ -80,60 +56,39 @@ func NewAPIClient(cfg *Configuration) *APIClient { if cfg.HTTPClient == nil { cfg.HTTPClient = http.DefaultClient } - - c := &APIClient{} - c.cfg = cfg - c.common.client = c - - // API Services - /*c.CloudsAPI = (*CloudsAPIService)(&c.common) - c.GroupsAPI = (*GroupsAPIService)(&c.common) - c.InstancesAPI = (*InstancesAPIService)(&c.common) - c.KeysCertsAPI = (*KeysCertsAPIService)(&c.common) - c.LibraryAPI = (*LibraryAPIService)(&c.common) - c.NetworksAPI = (*NetworksAPIService)(&c.common) - c.PlansAPI = (*PlansAPIService)(&c.common) - c.PoliciesAPI = (*PoliciesAPIService)(&c.common) - c.RolesAPI = (*RolesAPIService)(&c.common) - */ + c := &APIClient{ + cfg: cfg, + tokenFunc: defaultTokenFunc, + } return c } -// selectHeaderContentType select a content type from the available list. -func selectHeaderContentType(contentTypes []string) string { - if len(contentTypes) == 0 { - return "" +func (c *APIClient) SetMeta(meta interface{}, fn SetScmClientToken) error { + c.meta = meta + c.tokenFunc = fn + // if cmp version already set then skip + if c.cmpVersion != 0 { + return nil } - if contains(contentTypes, "application/json") { - return "application/json" + // initialize cmp status client and get setup/check + // and set version + cmpClient := CmpStatus{ + Client: c, + Cfg: *c.cfg, } - - return contentTypes[0] // use the first content type specified in 'consumes' -} - -// selectHeaderAccept join all accept types and return -func selectHeaderAccept(accepts []string) string { - if len(accepts) == 0 { - return "" - } - - if contains(accepts, "application/json") { - return "application/json" + // Get status of cmp + statusResp, err := cmpClient.GetCmpVersion(context.Background()) + if err != nil { + return err } - - return strings.Join(accepts, ",") -} - -// contains is a case insenstive match, finding needle in a haystack -func contains(haystack []string, needle string) bool { - for _, a := range haystack { - if strings.EqualFold(a, needle) { - return true - } + versionInt, err := parseVersion(statusResp.Appliance.BuildVersion) + if err != nil { + return fmt.Errorf("failed to parse cmp build, error: %v", err) } + c.cmpVersion = versionInt - return false + return nil } // callAPI do the request. @@ -146,6 +101,10 @@ func (c *APIClient) ChangeBasePath(path string) { c.cfg.BasePath = path } +func (c *APIClient) getVersion() int { + return c.cmpVersion +} + // prepareRequest build the request //nolint func (c *APIClient) prepareRequest( @@ -268,6 +227,9 @@ func (c *APIClient) prepareRequest( // Add the Authentication Token to header. if ctx != nil { + // Set auth token. This implementation is temporary fix. Need to put + // this in a goroutine or implement cache in cmp-api + c.tokenFunc(&ctx, c.meta) // add context to the request localVarRequest = localVarRequest.WithContext(ctx) // Basic HTTP Authentication @@ -306,146 +268,3 @@ func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err err return errors.New("undefined response type") } - -// Add a file to the multipart request -func addFile(w *multipart.Writer, fieldName, path string) error { - file, err := os.Open(path) - if err != nil { - return err - } - defer file.Close() - - part, err := w.CreateFormFile(fieldName, filepath.Base(path)) - if err != nil { - return err - } - _, err = io.Copy(part, file) - - return err -} - -// Set request body from an interface{} -func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { - if bodyBuf == nil { - bodyBuf = &bytes.Buffer{} - } - - switch v := body.(type) { - case io.Reader: - _, err = bodyBuf.ReadFrom(v) - case []byte: - _, err = bodyBuf.Write(v) - case string: - _, err = bodyBuf.WriteString(v) - case *string: - _, err = bodyBuf.WriteString(*v) - default: - if jsonCheck.MatchString(contentType) { - err = json.NewEncoder(bodyBuf).Encode(body) - } else if xmlCheck.MatchString(contentType) { - err = xml.NewEncoder(bodyBuf).Encode(body) - } - } - - if err != nil { - return nil, err - } - - if bodyBuf.Len() == 0 { - err = fmt.Errorf("invalid body type %s", contentType) - - return nil, err - } - - return bodyBuf, nil -} - -// detectContentType method is used to figure out `Request.Body` content type for request header -func detectContentType(body interface{}) string { - contentType := "text/plain; charset=utf-8" - kind := reflect.TypeOf(body).Kind() - - switch kind { - case reflect.Struct, reflect.Map, reflect.Ptr: - contentType = "application/json; charset=utf-8" - case reflect.String: - contentType = "text/plain; charset=utf-8" - default: - if b, ok := body.([]byte); ok { - contentType = http.DetectContentType(b) - } else if kind == reflect.Slice { - contentType = "application/json; charset=utf-8" - } - } - - return contentType -} - -// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go -type cacheControl map[string]string - -func parseCacheControl(headers http.Header) cacheControl { - cc := cacheControl{} - ccHeader := headers.Get("Cache-Control") - for _, part := range strings.Split(ccHeader, ",") { - part = strings.Trim(part, " ") - if part == "" { - continue - } - if strings.ContainsRune(part, '=') { - keyval := strings.Split(part, "=") - cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") - } else { - cc[part] = "" - } - } - - return cc -} - -// CacheExpires helper function to determine remaining time before repeating a request. -func CacheExpires(r *http.Response) time.Time { - // Figure out when the cache expires. - var expires time.Time - now, err := time.Parse(time.RFC1123, r.Header.Get("date")) - if err != nil { - return time.Now() - } - respCacheControl := parseCacheControl(r.Header) - if maxAge, ok := respCacheControl["max-age"]; ok { - if lifetime, err := time.ParseDuration(maxAge + "s"); err != nil { - expires = now - } else { - expires = now.Add(lifetime) - } - } else if expiresHeader := r.Header.Get("Expires"); expiresHeader != "" { - expires, err = time.Parse(time.RFC1123, expiresHeader) - if err != nil { - expires = now - } - } - - return expires -} - -// GenericSwaggerError Provides access to the body, error and model on returned errors. -type GenericSwaggerError struct { - body []byte - error string - model interface{} -} - -// Error returns non-empty string if there was an error. -func (e GenericSwaggerError) Error() string { - return e.error -} - -// Body returns the raw bytes of the response -func (e GenericSwaggerError) Body() []byte { - return e.body -} - -// Model returns the unpacked model of the error -func (e GenericSwaggerError) Model() interface{} { - return e.model -} diff --git a/pkg/client/clouds.go b/pkg/client/clouds.go index 65ecd22..fe757a2 100644 --- a/pkg/client/clouds.go +++ b/pkg/client/clouds.go @@ -32,8 +32,8 @@ func (a *CloudsAPIService) GetAllCloudDataStores(ctx context.Context, cloudID in allCloudDSAPI := &api{ method: "GET", - path: fmt.Sprintf("%s/%s/%s/%d/data-stores", a.Cfg.Host, consts.VmaasCmpAPIBasePath, - consts.ZonePath, cloudID), + path: fmt.Sprintf("%s/%s/%s/%d/%s", a.Cfg.Host, consts.VmaasCmpAPIBasePath, + consts.ZonePath, cloudID, consts.DatstorePath), client: a.Client, jsonParser: func(body []byte) error { diff --git a/pkg/client/clouds_test.go b/pkg/client/clouds_test.go index 598ff87..ce5f39e 100644 --- a/pkg/client/clouds_test.go +++ b/pkg/client/clouds_test.go @@ -51,6 +51,7 @@ func TestCloudsAPIService_GetAllCloudDataStores(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -81,6 +82,7 @@ func TestCloudsAPIService_GetAllCloudDataStores(t *testing.T) { path := mockHost + "/v1beta1/zones/1/data-stores" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -109,6 +111,7 @@ func TestCloudsAPIService_GetAllCloudDataStores(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -128,7 +131,9 @@ func TestCloudsAPIService_GetAllCloudDataStores(t *testing.T) { "name": templateName, }, cloudID: 0, - given: func(m *MockAPIClientHandler) {}, + given: func(m *MockAPIClientHandler) { + m.EXPECT().getVersion().Return(999999) + }, want: models.DataStoresResp{}, wantErr: true, }, @@ -187,6 +192,7 @@ func TestCloudsAPIService_GetAllCloudResourcePools(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -217,6 +223,7 @@ func TestCloudsAPIService_GetAllCloudResourcePools(t *testing.T) { path := mockHost + "/v1beta1/zones/1/resource-pools" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -244,6 +251,7 @@ func TestCloudsAPIService_GetAllCloudResourcePools(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -263,7 +271,9 @@ func TestCloudsAPIService_GetAllCloudResourcePools(t *testing.T) { "name": templateName, }, cloudID: 0, - given: func(m *MockAPIClientHandler) {}, + given: func(m *MockAPIClientHandler) { + m.EXPECT().getVersion().Return(999999) + }, want: models.ResourcePoolsResp{}, wantErr: true, }, @@ -320,6 +330,7 @@ func TestCloudsAPIService_GetAllClouds(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -349,6 +360,7 @@ func TestCloudsAPIService_GetAllClouds(t *testing.T) { path := mockHost + "/v1beta1/zones" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -375,6 +387,7 @@ func TestCloudsAPIService_GetAllClouds(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -444,6 +457,7 @@ func TestCloudsAPIService_GetAllCloudFolders(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -474,6 +488,7 @@ func TestCloudsAPIService_GetAllCloudFolders(t *testing.T) { path := mockHost + "/v1beta1/zones/1/folders" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -501,6 +516,7 @@ func TestCloudsAPIService_GetAllCloudFolders(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -569,6 +585,7 @@ func TestCloudsAPIService_GetAllCloudNetworks(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "zoneId": strconv.Itoa(1), @@ -600,6 +617,7 @@ func TestCloudsAPIService_GetAllCloudNetworks(t *testing.T) { path := mockHost + "/v1beta1/options/zoneNetworkOptions" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "zoneId": strconv.Itoa(1), @@ -626,6 +644,7 @@ func TestCloudsAPIService_GetAllCloudNetworks(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "zoneId": strconv.Itoa(1), @@ -694,6 +713,7 @@ func TestCloudsAPIService_GetSpecificCloudFolder(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -718,6 +738,7 @@ func TestCloudsAPIService_GetSpecificCloudFolder(t *testing.T) { path := mockHost + "/v1beta1/zones/1/folders/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -741,6 +762,7 @@ func TestCloudsAPIService_GetSpecificCloudFolder(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -756,9 +778,11 @@ func TestCloudsAPIService_GetSpecificCloudFolder(t *testing.T) { name: "Failed Test case 4: Cloud ID can not be less than 1", cloudID: 0, folderID: 1, - given: func(m *MockAPIClientHandler) {}, - want: models.GetSpecificCloudFolder{}, - wantErr: true, + given: func(m *MockAPIClientHandler) { + m.EXPECT().getVersion().Return(999999) + }, + want: models.GetSpecificCloudFolder{}, + wantErr: true, }, } for _, tt := range tests { diff --git a/pkg/client/domain_test.go b/pkg/client/domain_test.go index 8995935..01c9602 100644 --- a/pkg/client/domain_test.go +++ b/pkg/client/domain_test.go @@ -47,6 +47,7 @@ func TestDomainAPIService_GetAllDomains(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -76,6 +77,7 @@ func TestDomainAPIService_GetAllDomains(t *testing.T) { path := mockHost + "/v1beta1/networks/domains" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -102,6 +104,7 @@ func TestDomainAPIService_GetAllDomains(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -168,6 +171,7 @@ func TestDomainAPIService_GetSpecificDomain(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -191,6 +195,7 @@ func TestDomainAPIService_GetSpecificDomain(t *testing.T) { path := mockHost + "/v1beta1/networks/domains/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -213,6 +218,7 @@ func TestDomainAPIService_GetSpecificDomain(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) diff --git a/pkg/client/environment_test.go b/pkg/client/environment_test.go index 149e8e4..86444da 100644 --- a/pkg/client/environment_test.go +++ b/pkg/client/environment_test.go @@ -48,6 +48,7 @@ func TestEnvironmentAPIService_GetAllEnvironment(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -76,6 +77,7 @@ func TestEnvironmentAPIService_GetAllEnvironment(t *testing.T) { path := mockHost + "/v1beta1/environments" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -102,6 +104,7 @@ func TestEnvironmentAPIService_GetAllEnvironment(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/groups_test.go b/pkg/client/groups_test.go index 30cbe60..8ccc455 100644 --- a/pkg/client/groups_test.go +++ b/pkg/client/groups_test.go @@ -46,6 +46,7 @@ func TestGroupsAPIService_GetASpecificGroup(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -69,6 +70,7 @@ func TestGroupsAPIService_GetASpecificGroup(t *testing.T) { path := mockHost + "/v1beta1/groups/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -91,6 +93,7 @@ func TestGroupsAPIService_GetASpecificGroup(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -158,6 +161,7 @@ func TestGroupsAPIService_GetAllGroups(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -187,6 +191,7 @@ func TestGroupsAPIService_GetAllGroups(t *testing.T) { path := mockHost + "/v1beta1/groups" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -213,6 +218,7 @@ func TestGroupsAPIService_GetAllGroups(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/helper.go b/pkg/client/helper.go index 1657c5b..e2b084f 100644 --- a/pkg/client/helper.go +++ b/pkg/client/helper.go @@ -3,9 +3,26 @@ package client import ( + "bytes" "encoding/json" + "encoding/xml" + "fmt" + "io" + "mime/multipart" "net/http" "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + jsonCheck = regexp.MustCompile("(?i:[application|text]/json)") + xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)") + errVersion = fmt.Errorf("error, API is not supported for the current version, please contact your administrator") ) func getURLValues(query map[string]string) url.Values { @@ -55,3 +72,134 @@ func ParseError(resp *http.Response) error { return customErr } + +func parseVersion(version string) (int, error) { + if version == "" { + return 0, nil + } + + versionSplit := strings.Split(version, ".") + + mul := 10000 + sum := 0 + for _, v := range versionSplit { + vInt, err := strconv.Atoi(v) + if err != nil { + return 0, err + } + sum += mul * vInt + mul /= 100 + } + + return sum, nil +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insenstive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.EqualFold(a, needle) { + return true + } + } + + return false +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + switch v := body.(type) { + case io.Reader: + _, err = bodyBuf.ReadFrom(v) + case []byte: + _, err = bodyBuf.Write(v) + case string: + _, err = bodyBuf.WriteString(v) + case *string: + _, err = bodyBuf.WriteString(*v) + default: + if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + err = xml.NewEncoder(bodyBuf).Encode(body) + } + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("invalid body type %s", contentType) + + return nil, err + } + + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} diff --git a/pkg/client/helper_test.go b/pkg/client/helper_test.go index 7716c5e..6c0ecbb 100644 --- a/pkg/client/helper_test.go +++ b/pkg/client/helper_test.go @@ -3,6 +3,8 @@ package client import ( + "testing" + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" ) @@ -13,3 +15,43 @@ func getDefaultHeaders() map[string]string { "Accept": consts.ContentType, } } + +func Test_parseVersion(t *testing.T) { + tests := []struct { + name string + args string + want int + wantErr bool + }{ + { + name: "Normal test case 1: version = 8", + args: "8.0.0", + want: 80000, + wantErr: false, + }, + { + name: "Normal test case 2: version = 5.3.12", + args: "5.3.12", + want: 50312, + wantErr: false, + }, + { + name: "Normal test case 2: version = 99.88.77", + args: "99.88.77", + want: 998877, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseVersion(tt.args) + if (err != nil) != tt.wantErr { + t.Errorf("parseVersion() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("parseVersion() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/client/instances_test.go b/pkg/client/instances_test.go index 1d713da..f892cbf 100644 --- a/pkg/client/instances_test.go +++ b/pkg/client/instances_test.go @@ -62,6 +62,7 @@ func TestInstancesAPIService_CloneAnInstance(t *testing.T) { Name: "Instance_Clone", } // pBody := []byte(`{"zoneId":"1","CloneName":"Instance_Clone"}`) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -95,6 +96,7 @@ func TestInstancesAPIService_CloneAnInstance(t *testing.T) { Name: "Instance_Clone", } // pBody := []byte(`{"ZoneID":"1","CloneName":"Instance_Clone"}`) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -138,6 +140,7 @@ func TestInstancesAPIService_CloneAnInstance(t *testing.T) { }, Name: "Instance_Clone", } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -214,6 +217,7 @@ func TestInstancesAPIService_CreateAnInstance(t *testing.T) { CloneName: "Instance_Create", } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -245,6 +249,7 @@ func TestInstancesAPIService_CreateAnInstance(t *testing.T) { ZoneID: "1", CloneName: "Instance_Create", } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -281,6 +286,7 @@ func TestInstancesAPIService_CreateAnInstance(t *testing.T) { ZoneID: "1", CloneName: "Instance_Create", } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -340,6 +346,7 @@ func TestInstancesAPIService_DeleteAnInstance(t *testing.T) { "message": "Successfully Deleted the instance" } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -361,6 +368,7 @@ func TestInstancesAPIService_DeleteAnInstance(t *testing.T) { path := mockHost + "/v1beta1/instances/1" method := "DELETE" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(ctx, path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -383,6 +391,7 @@ func TestInstancesAPIService_DeleteAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(ctx, path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -452,6 +461,7 @@ func TestInstancesAPIService_ImportSnapshotOfAnInstance(t *testing.T) { pBody := &models.ImportSnapshotBody{ StorageProviderID: 1, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -478,6 +488,7 @@ func TestInstancesAPIService_ImportSnapshotOfAnInstance(t *testing.T) { pBody := &models.ImportSnapshotBody{ StorageProviderID: 1, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -509,6 +520,7 @@ func TestInstancesAPIService_ImportSnapshotOfAnInstance(t *testing.T) { pBody := &models.ImportSnapshotBody{ StorageProviderID: 1, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -595,6 +607,7 @@ func TestInstancesAPIService_ResizeAnInstance(t *testing.T) { }}, DeleteOriginalVolumes: false, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -636,6 +649,7 @@ func TestInstancesAPIService_ResizeAnInstance(t *testing.T) { }}, DeleteOriginalVolumes: false, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -683,6 +697,7 @@ func TestInstancesAPIService_ResizeAnInstance(t *testing.T) { }}, DeleteOriginalVolumes: false, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -762,6 +777,7 @@ func TestInstancesAPIService_SnapshotAnInstance(t *testing.T) { Description: "test_snapshot_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -797,6 +813,7 @@ func TestInstancesAPIService_SnapshotAnInstance(t *testing.T) { Description: "test_snapshot_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -838,6 +855,7 @@ func TestInstancesAPIService_SnapshotAnInstance(t *testing.T) { Description: "test_snapshot_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -916,6 +934,7 @@ func TestInstancesAPIService_UpdatingAnInstance(t *testing.T) { Description: "test_update_instance_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -950,6 +969,7 @@ func TestInstancesAPIService_UpdatingAnInstance(t *testing.T) { Description: "test_update_instance_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -990,6 +1010,7 @@ func TestInstancesAPIService_UpdatingAnInstance(t *testing.T) { Description: "test_update_instance_description", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, &pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1052,6 +1073,7 @@ func TestInstancesAPIService_GetASpecificInstance(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1076,6 +1098,7 @@ func TestInstancesAPIService_GetASpecificInstance(t *testing.T) { method := "GET" headers := getDefaultHeaders() // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1099,6 +1122,7 @@ func TestInstancesAPIService_GetASpecificInstance(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1166,6 +1190,7 @@ func TestInstancesAPIService_GetAllInstances(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -1196,6 +1221,7 @@ func TestInstancesAPIService_GetAllInstances(t *testing.T) { path := mockHost + "/v1beta1/instances" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -1222,6 +1248,7 @@ func TestInstancesAPIService_GetAllInstances(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -1287,6 +1314,7 @@ func TestInstancesAPIService_GetListOfSnapshotsForAnInstance(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1312,6 +1340,7 @@ func TestInstancesAPIService_GetListOfSnapshotsForAnInstance(t *testing.T) { path := mockHost + "/v1beta1/instances/1/snapshots" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1334,6 +1363,7 @@ func TestInstancesAPIService_GetListOfSnapshotsForAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1406,6 +1436,7 @@ func TestInstancesAPIService_GetInstanceHistory(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1438,6 +1469,7 @@ func TestInstancesAPIService_GetInstanceHistory(t *testing.T) { path := mockHost + "/v1beta1/instances/1/history" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1460,6 +1492,7 @@ func TestInstancesAPIService_GetInstanceHistory(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1521,6 +1554,7 @@ func TestInstancesAPIService_RestartAnInstance(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1541,6 +1575,7 @@ func TestInstancesAPIService_RestartAnInstance(t *testing.T) { method := "PUT" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1563,6 +1598,7 @@ func TestInstancesAPIService_RestartAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1621,6 +1657,7 @@ func TestInstancesAPIService_StartAnInstance(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1641,6 +1678,7 @@ func TestInstancesAPIService_StartAnInstance(t *testing.T) { method := "PUT" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1663,6 +1701,7 @@ func TestInstancesAPIService_StartAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1721,6 +1760,7 @@ func TestInstancesAPIService_StopAnInstance(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1741,6 +1781,7 @@ func TestInstancesAPIService_StopAnInstance(t *testing.T) { method := "PUT" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1763,6 +1804,7 @@ func TestInstancesAPIService_StopAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1821,6 +1863,7 @@ func TestInstancesAPIService_SuspendAnInstance(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -1841,6 +1884,7 @@ func TestInstancesAPIService_SuspendAnInstance(t *testing.T) { method := "PUT" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -1863,6 +1907,7 @@ func TestInstancesAPIService_SuspendAnInstance(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ diff --git a/pkg/client/library_test.go b/pkg/client/library_test.go index fb39528..a7ba251 100644 --- a/pkg/client/library_test.go +++ b/pkg/client/library_test.go @@ -49,6 +49,7 @@ func TestLibraryAPIService_GetAllLayouts(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -78,6 +79,7 @@ func TestLibraryAPIService_GetAllLayouts(t *testing.T) { path := mockHost + "/v1beta1/library/layouts" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -105,6 +107,7 @@ func TestLibraryAPIService_GetAllLayouts(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -174,6 +177,7 @@ func TestLibraryAPIService_GetAllInstanceTypes(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -203,6 +207,7 @@ func TestLibraryAPIService_GetAllInstanceTypes(t *testing.T) { path := mockHost + "/v1beta1/library/instance-types" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -229,6 +234,7 @@ func TestLibraryAPIService_GetAllInstanceTypes(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/networks.go b/pkg/client/networks.go index 0a448aa..0a42f90 100644 --- a/pkg/client/networks.go +++ b/pkg/client/networks.go @@ -11,6 +11,8 @@ import ( "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" ) +const networkCompatibleVersion = "5.2.10" + type NetworksAPIService struct { Client APIClientHandler Cfg Configuration @@ -60,9 +62,10 @@ func (n *NetworksAPIService) CreateNetwork( ) (models.CreateNetworkResponse, error) { var networksResp models.CreateNetworkResponse networkAPI := &api{ - method: "POST", - path: fmt.Sprintf("%s/%s/%s", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath), - client: n.Client, + compatibleVersion: networkCompatibleVersion, + method: "POST", + path: fmt.Sprintf("%s/%s/%s", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath), + client: n.Client, jsonParser: func(body []byte) error { return json.Unmarshal(body, &networksResp) @@ -79,9 +82,10 @@ func (n *NetworksAPIService) DeleteNetwork( ) (models.SuccessOrErrorMessage, error) { var output models.SuccessOrErrorMessage networkAPI := &api{ - method: "DELETE", - path: fmt.Sprintf("%s/%s/%s/%d", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, networkID), - client: n.Client, + compatibleVersion: networkCompatibleVersion, + method: "DELETE", + path: fmt.Sprintf("%s/%s/%s/%d", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, networkID), + client: n.Client, jsonParser: func(body []byte) error { return json.Unmarshal(body, &output) @@ -98,9 +102,10 @@ func (n *NetworksAPIService) GetNetworkType( ) (models.GetNetworkTypesResponse, error) { var resp models.GetNetworkTypesResponse networkAPI := &api{ - method: "GET", - path: fmt.Sprintf("%s/%s/%s", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworkTypePath), - client: n.Client, + compatibleVersion: networkCompatibleVersion, + method: "GET", + path: fmt.Sprintf("%s/%s/%s", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworkTypePath), + client: n.Client, jsonParser: func(body []byte) error { return json.Unmarshal(body, &resp) @@ -157,9 +162,10 @@ func (n *NetworksAPIService) UpdateNetwork( ) (models.SuccessOrErrorMessage, error) { var output models.SuccessOrErrorMessage networkAPI := &api{ - method: "PUT", - path: fmt.Sprintf("%s/%s/%s/%d", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, networkID), - client: n.Client, + compatibleVersion: networkCompatibleVersion, + method: "PUT", + path: fmt.Sprintf("%s/%s/%s/%d", n.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, networkID), + client: n.Client, jsonParser: func(body []byte) error { return json.Unmarshal(body, &output) diff --git a/pkg/client/networks_test.go b/pkg/client/networks_test.go index e7b47ca..22d1916 100644 --- a/pkg/client/networks_test.go +++ b/pkg/client/networks_test.go @@ -49,6 +49,7 @@ func TestNetworksAPIService_GetAllNetworks(t *testing.T) { "networkCount": 1 } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -79,6 +80,7 @@ func TestNetworksAPIService_GetAllNetworks(t *testing.T) { path := mockHost + "/v1beta1/networks" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -105,6 +107,7 @@ func TestNetworksAPIService_GetAllNetworks(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -165,6 +168,7 @@ func TestNetworksAPIService_CreateNetwork(t *testing.T) { headers := getDefaultHeaders() req, _ := http.NewRequest(method, path, nil) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, models.CreateNetworkRequest{ Network: models.CreateNetwork{ @@ -250,6 +254,7 @@ func TestNetworksAPIService_UpdateNetwork(t *testing.T) { headers := getDefaultHeaders() req, _ := http.NewRequest(method, path, nil) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, models.CreateNetworkRequest{ Network: models.CreateNetwork{ @@ -325,6 +330,7 @@ func TestNetworksAPIService_GetNetworkProxy(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": "NSXT", @@ -397,6 +403,7 @@ func TestNetworksAPIService_GetSpecificNetwork(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -420,6 +427,7 @@ func TestNetworksAPIService_GetSpecificNetwork(t *testing.T) { path := mockHost + "/v1beta1/networks/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) }, @@ -442,6 +450,7 @@ func TestNetworksAPIService_GetSpecificNetwork(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -504,6 +513,7 @@ func TestNetworksAPIService_DeleteNetwork(t *testing.T) { "message": "test_template_delete_network" } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -525,6 +535,7 @@ func TestNetworksAPIService_DeleteNetwork(t *testing.T) { path := mockHost + "/v1beta1/networks/1" method := "DELETE" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) }, @@ -547,6 +558,7 @@ func TestNetworksAPIService_DeleteNetwork(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -614,6 +626,7 @@ func TestNetworksAPIService_GetNetworkType(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -643,6 +656,7 @@ func TestNetworksAPIService_GetNetworkType(t *testing.T) { path := mockHost + "/v1beta1/network-types" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -669,6 +683,7 @@ func TestNetworksAPIService_GetNetworkType(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -738,6 +753,7 @@ func TestNetworksAPIService_GetNetworkPool(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -767,6 +783,7 @@ func TestNetworksAPIService_GetNetworkPool(t *testing.T) { path := mockHost + "/v1beta1/networks/pools" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -793,6 +810,7 @@ func TestNetworksAPIService_GetNetworkPool(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -859,6 +877,7 @@ func TestNetworksAPIService_GetSpecificNetworkPool(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -882,6 +901,7 @@ func TestNetworksAPIService_GetSpecificNetworkPool(t *testing.T) { path := mockHost + "/v1beta1/networks/pools/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) }, @@ -904,6 +924,7 @@ func TestNetworksAPIService_GetSpecificNetworkPool(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) diff --git a/pkg/client/plans_test.go b/pkg/client/plans_test.go index e9988f5..32424b5 100644 --- a/pkg/client/plans_test.go +++ b/pkg/client/plans_test.go @@ -49,6 +49,7 @@ func TestPlansAPIService_GetAllServicePlans(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -78,6 +79,7 @@ func TestPlansAPIService_GetAllServicePlans(t *testing.T) { path := mockHost + "/v1beta1/service-plans" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -104,6 +106,7 @@ func TestPlansAPIService_GetAllServicePlans(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/power_schedule_test.go b/pkg/client/power_schedule_test.go index 0d69a35..9bcd027 100644 --- a/pkg/client/power_schedule_test.go +++ b/pkg/client/power_schedule_test.go @@ -48,6 +48,7 @@ func TestPowerSchedulesAPIService_GetAllPowerSchedules(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -77,6 +78,7 @@ func TestPowerSchedulesAPIService_GetAllPowerSchedules(t *testing.T) { path := mockHost + "/v1beta1/power-schedules" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -103,6 +105,7 @@ func TestPowerSchedulesAPIService_GetAllPowerSchedules(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/provisioning_test.go b/pkg/client/provisioning_test.go index e6324b0..67d8738 100644 --- a/pkg/client/provisioning_test.go +++ b/pkg/client/provisioning_test.go @@ -46,6 +46,7 @@ func TestProvisioningAPIService_GetAllProvisioningTypes(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -75,6 +76,7 @@ func TestProvisioningAPIService_GetAllProvisioningTypes(t *testing.T) { path := mockHost + "/v1beta1/provision-types" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -101,6 +103,7 @@ func TestProvisioningAPIService_GetAllProvisioningTypes(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/client/router.go b/pkg/client/router.go index 70eb62e..55647f2 100644 --- a/pkg/client/router.go +++ b/pkg/client/router.go @@ -11,6 +11,8 @@ import ( "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" ) +const routerCompatibleVersion = "5.2.10" + type RouterAPIService struct { Client APIClientHandler Cfg Configuration @@ -22,7 +24,8 @@ func (r *RouterAPIService) GetAllRouter( ) (models.GetAllNetworkRouter, error) { routerResp := models.GetAllNetworkRouter{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath), client: r.Client, @@ -41,7 +44,8 @@ func (r *RouterAPIService) GetSpecificRouter( ) (models.GetNetworkRouter, error) { routerResp := models.GetNetworkRouter{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID), client: r.Client, @@ -60,7 +64,8 @@ func (r *RouterAPIService) CreateRouter( ) (models.CreateRouterResp, error) { routerResp := models.CreateRouterResp{} routerAPI := &api{ - method: "POST", + compatibleVersion: routerCompatibleVersion, + method: "POST", path: fmt.Sprintf("%s/%s/%s/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath), client: r.Client, @@ -80,7 +85,8 @@ func (r *RouterAPIService) UpdateRouter( ) (models.SuccessOrErrorMessage, error) { routerResp := models.SuccessOrErrorMessage{} routerAPI := &api{ - method: "PUT", + compatibleVersion: routerCompatibleVersion, + method: "PUT", path: fmt.Sprintf("%s/%s/%s/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID), client: r.Client, @@ -99,7 +105,8 @@ func (r *RouterAPIService) DeleteRouter( ) (models.SuccessOrErrorMessage, error) { routerResp := models.SuccessOrErrorMessage{} routerAPI := &api{ - method: "DELETE", + compatibleVersion: routerCompatibleVersion, + method: "DELETE", path: fmt.Sprintf("%s/%s/%s/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID), client: r.Client, @@ -118,7 +125,8 @@ func (r *RouterAPIService) GetRouterTypes( ) (models.GetNetworlRouterTypes, error) { routerResp := models.GetNetworlRouterTypes{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworkRouterTypePath), client: r.Client, @@ -137,7 +145,8 @@ func (r *RouterAPIService) GetNetworkServices( ) (models.GetNetworkServicesResp, error) { routerResp := models.GetNetworkServicesResp{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkServicePath), client: r.Client, @@ -157,7 +166,8 @@ func (r *RouterAPIService) CreateRouterNat( ) (models.CreateRouterNatResponse, error) { natResp := models.CreateRouterNatResponse{} routerAPI := &api{ - method: "POST", + compatibleVersion: routerCompatibleVersion, + method: "POST", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersNatPath), client: r.Client, @@ -176,7 +186,8 @@ func (r *RouterAPIService) GetSpecificRouterNat( ) (models.GetSpecificRouterNatResponse, error) { natResp := models.GetSpecificRouterNatResponse{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersNatPath, natID), @@ -197,7 +208,8 @@ func (r *RouterAPIService) UpdateRouterNat( ) (models.CreateRouterNatResponse, error) { natResp := models.CreateRouterNatResponse{} routerAPI := &api{ - method: "PUT", + compatibleVersion: routerCompatibleVersion, + method: "PUT", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersNatPath, natID), @@ -217,7 +229,8 @@ func (r *RouterAPIService) DeleteRouterNat( ) (models.SuccessOrErrorMessage, error) { natResp := models.SuccessOrErrorMessage{} routerAPI := &api{ - method: "DELETE", + compatibleVersion: routerCompatibleVersion, + method: "DELETE", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersNatPath, natID), @@ -238,7 +251,8 @@ func (r *RouterAPIService) CreateRouterFirewallRuleGroup( ) (models.CreateRouterFirewallRuleGroupResponse, error) { firewallGroupResp := models.CreateRouterFirewallRuleGroupResponse{} routerAPI := &api{ - method: "POST", + compatibleVersion: routerCompatibleVersion, + method: "POST", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersFirewallRuleGroupPath), client: r.Client, @@ -257,7 +271,8 @@ func (r *RouterAPIService) GetSpecificRouterFirewallRuleGroup( ) (models.GetSpecificRouterFirewallRuleGroupResponse, error) { firewallGroupResp := models.GetSpecificRouterFirewallRuleGroupResponse{} routerAPI := &api{ - method: "GET", + compatibleVersion: routerCompatibleVersion, + method: "GET", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersFirewallRuleGroupPath, firewallGroupID), @@ -277,7 +292,8 @@ func (r *RouterAPIService) DeleteRouterFirewallRuleGroup( ) (models.SuccessOrErrorMessage, error) { firewallGroupResp := models.SuccessOrErrorMessage{} routerAPI := &api{ - method: "DELETE", + compatibleVersion: routerCompatibleVersion, + method: "DELETE", path: fmt.Sprintf("%s/%s/%s/%s/%d/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, consts.NetworksPath, consts.NetworkRouterPath, routerID, consts.RoutersFirewallRuleGroupPath, firewallGroupID), diff --git a/pkg/client/router_test.go b/pkg/client/router_test.go index e18548f..c7522f1 100644 --- a/pkg/client/router_test.go +++ b/pkg/client/router_test.go @@ -49,6 +49,7 @@ func TestRouterAPIService_GetAllRouters(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -78,6 +79,7 @@ func TestRouterAPIService_GetAllRouters(t *testing.T) { path := mockHost + "/v1beta1/networks/routers" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -104,6 +106,7 @@ func TestRouterAPIService_GetAllRouters(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -172,6 +175,7 @@ func TestRouterAPIService_GetNetworkRouterTypes(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -201,6 +205,7 @@ func TestRouterAPIService_GetNetworkRouterTypes(t *testing.T) { path := mockHost + "/v1beta1/network-router-types" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -227,6 +232,7 @@ func TestRouterAPIService_GetNetworkRouterTypes(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -287,6 +293,7 @@ func TestRouterAPIService_CreateRouter(t *testing.T) { headers := getDefaultHeaders() req, _ := http.NewRequest(method, path, nil) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, models.CreateRouterRequest{ NetworkRouter: models.CreateRouterRequestRouter{ @@ -374,6 +381,7 @@ func TestRouterAPIService_UpdateRouter(t *testing.T) { Name: "test_update_router_name", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -403,6 +411,7 @@ func TestRouterAPIService_UpdateRouter(t *testing.T) { Name: "test_update_router_name", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -440,6 +449,7 @@ func TestRouterAPIService_UpdateRouter(t *testing.T) { Name: "test_update_router_name", }, } + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) m.EXPECT().callAPI(req).Return(&http.Response{ @@ -500,6 +510,7 @@ func TestRouterAPIService_GetSpecificRouter(t *testing.T) { "name": "test_template_get_a_specific_router" } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -521,6 +532,7 @@ func TestRouterAPIService_GetSpecificRouter(t *testing.T) { path := mockHost + "/v1beta1/networks/routers/1" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) }, @@ -543,6 +555,7 @@ func TestRouterAPIService_GetSpecificRouter(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -604,6 +617,7 @@ func TestRouterAPIService_DeleteRouter(t *testing.T) { "message": "test_template_delete_a_router" } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -625,6 +639,7 @@ func TestRouterAPIService_DeleteRouter(t *testing.T) { path := mockHost + "/v1beta1/networks/routers/1" method := "DELETE" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) }, @@ -647,6 +662,7 @@ func TestRouterAPIService_DeleteRouter(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(nil), url.Values{}, "", nil).Return(req, nil) @@ -712,6 +728,7 @@ func TestRouterAPIService_GetNetworkServices(t *testing.T) { }] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -741,6 +758,7 @@ func TestRouterAPIService_GetNetworkServices(t *testing.T) { path := mockHost + "/v1beta1/networks/services" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -767,6 +785,7 @@ func TestRouterAPIService_GetNetworkServices(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -834,6 +853,7 @@ func TestRouterAPIService_DeleteRouterNat(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -903,6 +923,7 @@ func TestRouterAPIService_GetSpecificRouterNat(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -986,6 +1007,7 @@ func TestRouterAPIService_CreateRouterNat(t *testing.T) { "id": 2 } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, reqModel, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1070,6 +1092,7 @@ func TestRouterAPIService_UpdateRouterNat(t *testing.T) { "id": 2 } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, reqModel, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1143,6 +1166,7 @@ func TestRouterAPIService_DeleteRouterFirewallRuleGroup(t *testing.T) { "success": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1212,6 +1236,7 @@ func TestRouterAPIService_GetSpecificRouterFirewallRuleGroup(t *testing.T) { } } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -1295,6 +1320,7 @@ func TestRouterAPIService_CreateRouterFirewallRuleGroup(t *testing.T) { "id": 2 } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, reqModel, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) diff --git a/pkg/client/servers_test.go b/pkg/client/servers_test.go index 0b4d719..afd2097 100644 --- a/pkg/client/servers_test.go +++ b/pkg/client/servers_test.go @@ -49,6 +49,7 @@ func TestServersAPIService_GetAllServers(t *testing.T) { "multiTenant": true } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -79,6 +80,7 @@ func TestServersAPIService_GetAllServers(t *testing.T) { path := mockHost + "/v1beta1/servers" method := "GET" headers := getDefaultHeaders() + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -105,6 +107,7 @@ func TestServersAPIService_GetAllServers(t *testing.T) { ] } `))) + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -174,6 +177,7 @@ func TestServersAPIService_GetSpecificServer(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -198,6 +202,7 @@ func TestServersAPIService_GetSpecificServer(t *testing.T) { method := "GET" headers := getDefaultHeaders() // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) }, @@ -221,6 +226,7 @@ func TestServersAPIService_GetSpecificServer(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) @@ -235,9 +241,11 @@ func TestServersAPIService_GetSpecificServer(t *testing.T) { { name: "Failed test case 4: server ID should be greater than 0", serverID: 0, - given: func(m *MockAPIClientHandler) {}, - want: models.GetSpecificServerResponse{}, - wantErr: true, + given: func(m *MockAPIClientHandler) { + m.EXPECT().getVersion().Return(999999) + }, + want: models.GetSpecificServerResponse{}, + wantErr: true, }, } for _, tt := range tests { diff --git a/pkg/client/status.go b/pkg/client/status.go new file mode 100644 index 0000000..44ba096 --- /dev/null +++ b/pkg/client/status.go @@ -0,0 +1,35 @@ +// (C) Copyright 2021 Hewlett Packard Enterprise Development LP + +package client + +import ( + "context" + "encoding/json" + "fmt" + + consts "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/common" + "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" +) + +type CmpStatus struct { + Client APIClientHandler + Cfg Configuration +} + +func (a *CmpStatus) GetCmpVersion(ctx context.Context) (models.CmpVersionModel, error) { + checkResp := models.CmpVersionModel{} + + allCloudDSAPI := &api{ + method: "GET", + path: fmt.Sprintf("%s/%s/%s", a.Cfg.Host, consts.VmaasCmpAPIBasePath, + consts.WhoamiPath), + client: a.Client, + + jsonParser: func(body []byte) error { + return json.Unmarshal(body, &checkResp) + }, + } + err := allCloudDSAPI.do(ctx, nil, nil) + + return checkResp, err +} diff --git a/pkg/client/virtual_images_test.go b/pkg/client/virtual_images_test.go index 2f3a380..d55e594 100644 --- a/pkg/client/virtual_images_test.go +++ b/pkg/client/virtual_images_test.go @@ -50,6 +50,7 @@ func TestVirtualImagesAPIService_GetAllVirtualImages(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -80,6 +81,7 @@ func TestVirtualImagesAPIService_GetAllVirtualImages(t *testing.T) { method := "GET" headers := getDefaultHeaders() // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, @@ -107,6 +109,7 @@ func TestVirtualImagesAPIService_GetAllVirtualImages(t *testing.T) { } `))) // mock the context only since it is not validated in this function + m.EXPECT().getVersion().Return(999999) m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, getURLValues(map[string]string{ "name": templateName, diff --git a/pkg/common/constants.go b/pkg/common/constants.go index 8fe7863..c67667b 100644 --- a/pkg/common/constants.go +++ b/pkg/common/constants.go @@ -45,6 +45,7 @@ const ( OptionsPath = "options" ZoneNetworkOptionsPath = "zoneNetworkOptions" ProvisionTypesPath = "provision-types" + WhoamiPath = "whoami" // headers ContentType = "application/json" diff --git a/pkg/models/status.go b/pkg/models/status.go new file mode 100644 index 0000000..f3ddbcd --- /dev/null +++ b/pkg/models/status.go @@ -0,0 +1,10 @@ +// (C) Copyright 2021 Hewlett Packard Enterprise Development LP +package models + +type CmpVersionModel struct { + Appliance Appliance `json:"appliance"` +} + +type Appliance struct { + BuildVersion string `json:"buildVersion"` +} diff --git a/pkg/models/vmaas_provider.go b/pkg/models/vmaas_provider.go new file mode 100644 index 0000000..f12a5ef --- /dev/null +++ b/pkg/models/vmaas_provider.go @@ -0,0 +1,11 @@ +// (C) Copyright 2021 Hewlett Packard Enterprise Development LP +package models + +type TFVmaas struct { + Location string `tf:"location"` + SpaceName string `tf:"space_name"` +} + +type TFProvider struct { + Vmaas TFVmaas `tf:"vmaas,sub"` +}