From 69e977c34ea08a74ac264eb67863361a578c96a1 Mon Sep 17 00:00:00 2001 From: "Cuong. Duong Manh" Date: Fri, 24 May 2024 10:36:03 +0700 Subject: [PATCH] [feat] api get portal quota --- test/portal_test.go | 51 ++++++++++++++++ vngcloud/entity/portal.go | 22 +++++++ vngcloud/sdk_error/error_codes.go | 6 ++ vngcloud/sdk_error/quota.go | 11 ++++ vngcloud/services/portal/iportal.go | 7 ++- vngcloud/services/portal/v2/irequest.go | 5 ++ vngcloud/services/portal/v2/portal.go | 42 ++++++++++++++ vngcloud/services/portal/v2/portal_request.go | 15 +++++ .../services/portal/v2/portal_response.go | 58 +++++++++++++++++++ vngcloud/services/portal/v2/url.go | 10 ++++ 10 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 vngcloud/sdk_error/quota.go create mode 100644 vngcloud/services/portal/v2/irequest.go create mode 100644 vngcloud/services/portal/v2/portal.go create mode 100644 vngcloud/services/portal/v2/portal_request.go create mode 100644 vngcloud/services/portal/v2/portal_response.go create mode 100644 vngcloud/services/portal/v2/url.go diff --git a/test/portal_test.go b/test/portal_test.go index 333aa61..1c7400d 100644 --- a/test/portal_test.go +++ b/test/portal_test.go @@ -3,6 +3,7 @@ package test import ( lserr "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/sdk_error" lsportalV1 "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/services/portal/v1" + lsportalV2 "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/services/portal/v2" ltesting "testing" ) @@ -63,3 +64,53 @@ func TestGetPortalInfoFailure(t *ltesting.T) { t.Log("RESULT:", err) t.Log("PASS") } + +func TestListAllQuotaSuccess(t *ltesting.T) { + vngcloud := validSdkConfig() + quotas, err := vngcloud.VServerGateway().V2().PortalService().ListAllQuotaUsed() + + if err != nil { + t.Errorf("Expect error to be nil but got %+v", err) + } + + if quotas == nil { + t.Errorf("Expect quotas not to be nil but got nil") + } + + t.Log("RESULT:", quotas) + t.Log("PASS") +} + +func TestGetQuotaByNameFailure(t *ltesting.T) { + vngcloud := validSdkConfig() + opt := lsportalV2.NewGetQuotaByNameRequest("fake-quota-name") + quota, err := vngcloud.VServerGateway().V2().PortalService().GetQuotaByName(opt) + + if err == nil { + t.Errorf("Expect error but got nil") + } + + if quota != nil { + t.Errorf("Expect quota to be nil but got %+v", quota) + } + + t.Log("RESULT:", err) + t.Log("PASS") +} + +func TestGetQuotaByNamePass(t *ltesting.T) { + vngcloud := validSdkConfig() + opt := lsportalV2.NewGetQuotaByNameRequest(lsportalV2.QtVolumeAttachLimit) + quota, err := vngcloud.VServerGateway().V2().PortalService().GetQuotaByName(opt) + + if err != nil { + t.Errorf("Expect error to be nil but got %+v", err) + } + + if quota == nil { + t.Errorf("Expect quota not to be nil but got nil") + } + + t.Log("RESULT:", quota) + t.Log("PASS") +} diff --git a/vngcloud/entity/portal.go b/vngcloud/entity/portal.go index be36ce7..a6bb7c3 100644 --- a/vngcloud/entity/portal.go +++ b/vngcloud/entity/portal.go @@ -4,3 +4,25 @@ type Portal struct { ProjectID string UserID int } + +type Quota struct { + Description string + Name string + Type string + Limit int + Used int +} + +type ListQuotas struct { + Items []*Quota +} + +func (s *ListQuotas) FindQuotaByName(name string) *Quota { + for _, q := range s.Items { + if q.Name == name { + return q + } + } + + return nil +} diff --git a/vngcloud/sdk_error/error_codes.go b/vngcloud/sdk_error/error_codes.go index 035a892..335fe9e 100644 --- a/vngcloud/sdk_error/error_codes.go +++ b/vngcloud/sdk_error/error_codes.go @@ -66,3 +66,9 @@ const ( EcVServerServerDeleteDeletingServer = ErrorCode("VngCloudVServerServerDeleteDeletingServer") EcVServerServerDeleteBillingServer = ErrorCode("VngCloudVServerServerDeleteBillingServer") ) + +// vServer quota + +const ( + EcVServerQuotaNotFound = ErrorCode("VngCloudVServerQuotaNotFound") +) diff --git a/vngcloud/sdk_error/quota.go b/vngcloud/sdk_error/quota.go new file mode 100644 index 0000000..27c38bc --- /dev/null +++ b/vngcloud/sdk_error/quota.go @@ -0,0 +1,11 @@ +package sdk_error + +import lfmt "fmt" + +func WithErrorQuotaNotFound(_ IErrorRespone) func(sdkError ISdkError) { + return func(sdkError ISdkError) { + sdkError.WithErrorCode(EcVServerQuotaNotFound). + WithMessage("Quota not found"). + WithErrors(lfmt.Errorf("quota not found")) + } +} diff --git a/vngcloud/services/portal/iportal.go b/vngcloud/services/portal/iportal.go index 2f1bd56..cf5d92d 100644 --- a/vngcloud/services/portal/iportal.go +++ b/vngcloud/services/portal/iportal.go @@ -2,13 +2,16 @@ package portal import ( lsentity "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/entity" - lsdkErr "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/sdk_error" + lserr "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/sdk_error" lsportalV1 "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/services/portal/v1" + lsportalV2 "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/services/portal/v2" ) type IPortalServiceV1 interface { - GetPortalInfo(popts lsportalV1.IGetPortalInfoRequest) (*lsentity.Portal, lsdkErr.ISdkError) + GetPortalInfo(popts lsportalV1.IGetPortalInfoRequest) (*lsentity.Portal, lserr.ISdkError) } type IPortalServiceV2 interface { + ListAllQuotaUsed() (*lsentity.ListQuotas, lserr.ISdkError) + GetQuotaByName(popts lsportalV2.IGetQuotaByNameRequest) (*lsentity.Quota, lserr.ISdkError) } diff --git a/vngcloud/services/portal/v2/irequest.go b/vngcloud/services/portal/v2/irequest.go new file mode 100644 index 0000000..c7d0308 --- /dev/null +++ b/vngcloud/services/portal/v2/irequest.go @@ -0,0 +1,5 @@ +package v2 + +type IGetQuotaByNameRequest interface { + GetName() QuotaName +} diff --git a/vngcloud/services/portal/v2/portal.go b/vngcloud/services/portal/v2/portal.go new file mode 100644 index 0000000..db3a80d --- /dev/null +++ b/vngcloud/services/portal/v2/portal.go @@ -0,0 +1,42 @@ +package v2 + +import ( + lsclient "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/client" + lsentity "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/entity" + lserr "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/sdk_error" +) + +func (s *PortalServiceV2) ListAllQuotaUsed() (*lsentity.ListQuotas, lserr.ISdkError) { + url := listAllQuotaUsedUrl(s.PortalClient) + resp := new(ListAllQuotaUsedResponse) + errResp := lserr.NewErrorResponse(lserr.NormalErrorType) + req := lsclient.NewRequest(). + WithOkCodes(200). + WithJsonResponse(resp). + WithJsonError(errResp) + + if _, sdkErr := s.PortalClient.Get(url, req); sdkErr != nil { + return nil, lserr.SdkErrorHandler(sdkErr, errResp). + WithKVparameters("projectId", s.getProjectId()) + } + + return resp.ToEntityListQuotas(), nil +} + +func (s *PortalServiceV2) GetQuotaByName(popts IGetQuotaByNameRequest) (*lsentity.Quota, lserr.ISdkError) { + listQuotas, sdkErr := s.ListAllQuotaUsed() + if sdkErr != nil { + return nil, sdkErr + } + + quota := listQuotas.FindQuotaByName(string(popts.GetName())) + if quota == nil { + return nil, lserr.ErrorHandler(nil, lserr.WithErrorQuotaNotFound(nil)).WithKVparameters("quotaName", popts.GetName()) + } + + return quota, nil +} + +func (s *PortalServiceV2) getProjectId() string { + return s.PortalClient.GetProjectId() +} diff --git a/vngcloud/services/portal/v2/portal_request.go b/vngcloud/services/portal/v2/portal_request.go new file mode 100644 index 0000000..80418fe --- /dev/null +++ b/vngcloud/services/portal/v2/portal_request.go @@ -0,0 +1,15 @@ +package v2 + +type GetQuotaByNameRequest struct { + Name QuotaName +} + +func NewGetQuotaByNameRequest(pname QuotaName) IGetQuotaByNameRequest { + return &GetQuotaByNameRequest{ + Name: pname, + } +} + +func (s *GetQuotaByNameRequest) GetName() QuotaName { + return s.Name +} diff --git a/vngcloud/services/portal/v2/portal_response.go b/vngcloud/services/portal/v2/portal_response.go new file mode 100644 index 0000000..afd1d44 --- /dev/null +++ b/vngcloud/services/portal/v2/portal_response.go @@ -0,0 +1,58 @@ +package v2 + +import ( + lstrconv "strconv" + + lsentity "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/entity" +) + +const ( + QtVolumeAttachLimit = QuotaName("VOLUME_PER_SERVER") // The maximum number of volumes that you can attach to an server +) + +type ( + Quota struct { + Description string `json:"description,omitempty"` + Name QuotaName `json:"quotaName"` + Type QuotaType `json:"type"` + Used string `json:"used"` + Limit int `json:"limit"` + } + + QuotaType string + QuotaName string +) + +type ListAllQuotaUsedResponse struct { + Data []Quota `json:"data"` +} + +func (s *ListAllQuotaUsedResponse) ToEntityListQuotas() *lsentity.ListQuotas { + listQuotas := &lsentity.ListQuotas{ + Items: make([]*lsentity.Quota, 0), + } + for _, q := range s.Data { + listQuotas.Items = append(listQuotas.Items, q.ToEntityQuota()) + } + + return listQuotas +} + +func (s *Quota) ToEntityQuota() *lsentity.Quota { + var ( + used int + err error + ) + + if used, err = lstrconv.Atoi(s.Used); err != nil { + used = 0 + } + + return &lsentity.Quota{ + Description: s.Description, + Name: string(s.Name), + Type: string(s.Type), + Limit: s.Limit, + Used: used, + } +} diff --git a/vngcloud/services/portal/v2/url.go b/vngcloud/services/portal/v2/url.go new file mode 100644 index 0000000..9eb9978 --- /dev/null +++ b/vngcloud/services/portal/v2/url.go @@ -0,0 +1,10 @@ +package v2 + +import lsclient "github.com/vngcloud/vngcloud-go-sdk/v2/vngcloud/client" + +func listAllQuotaUsedUrl(psc lsclient.IServiceClient) string { + return psc.ServiceURL( + psc.GetProjectId(), + "quotas", + "quotaUsed") +}