From 8b82ce228010038de7dce809f7fa86b9d4e8de51 Mon Sep 17 00:00:00 2001 From: anton-sidelnikov Date: Tue, 15 Oct 2024 18:04:30 +0200 Subject: [PATCH] [Feat.] RMS query endpoints and tests --- acceptance/clients/clients.go | 11 ++ acceptance/openstack/rms/v1/query_test.go | 186 ++++++++++++++++++ acceptance/tools/tools.go | 28 +++ openstack/client.go | 4 + openstack/css/v1/clusters/Create.go | 3 +- openstack/rms/query/GetAnyResource.go | 20 ++ openstack/rms/query/GetCount.go | 42 ++++ openstack/rms/query/GetRecordedResource.go | 20 ++ openstack/rms/query/GetResource.go | 20 ++ openstack/rms/query/ListAllResources.go | 44 +++++ openstack/rms/query/ListAllResourcesTags.go | 36 ++++ .../rms/query/ListRecordeResourceTags.go | 61 ++++++ openstack/rms/query/ListRecordedResources.go | 47 +++++ .../rms/query/ListRecordedResourcesSummary.go | 77 ++++++++ openstack/rms/query/ListResourcesSummary.go | 40 ++++ openstack/rms/query/ListServices.go | 86 ++++++++ openstack/rms/query/ListSpecificType.go | 85 ++++++++ 17 files changed, 809 insertions(+), 1 deletion(-) create mode 100644 acceptance/openstack/rms/v1/query_test.go create mode 100644 openstack/rms/query/GetAnyResource.go create mode 100644 openstack/rms/query/GetCount.go create mode 100644 openstack/rms/query/GetRecordedResource.go create mode 100644 openstack/rms/query/GetResource.go create mode 100644 openstack/rms/query/ListAllResources.go create mode 100644 openstack/rms/query/ListAllResourcesTags.go create mode 100644 openstack/rms/query/ListRecordeResourceTags.go create mode 100644 openstack/rms/query/ListRecordedResources.go create mode 100644 openstack/rms/query/ListRecordedResourcesSummary.go create mode 100644 openstack/rms/query/ListResourcesSummary.go create mode 100644 openstack/rms/query/ListServices.go create mode 100644 openstack/rms/query/ListSpecificType.go diff --git a/acceptance/clients/clients.go b/acceptance/clients/clients.go index f2076798d..011ee8bac 100644 --- a/acceptance/clients/clients.go +++ b/acceptance/clients/clients.go @@ -882,6 +882,17 @@ func NewEVPNClient() (client *golangsdk.ServiceClient, err error) { }) } +// NewRMSClient returns authenticated RMS v1 client +func NewRMSClient() (client *golangsdk.ServiceClient, err error) { + cc, err := CloudAndClient() + if err != nil { + return nil, err + } + return openstack.NewRmsServiceV1(cc.ProviderClient, golangsdk.EndpointOpts{ + Region: cc.RegionName, + }) +} + func UpdatePeerTenantDetails(cloud *openstack.Cloud) error { if id := EnvOS.GetEnv("Peer_Tenant_ID"); id != "" { cloud.AuthInfo.ProjectID = id diff --git a/acceptance/openstack/rms/v1/query_test.go b/acceptance/openstack/rms/v1/query_test.go new file mode 100644 index 000000000..05215ee31 --- /dev/null +++ b/acceptance/openstack/rms/v1/query_test.go @@ -0,0 +1,186 @@ +package v1 + +import ( + "testing" + + "github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients" + "github.com/opentelekomcloud/gophertelekomcloud/acceptance/tools" + "github.com/opentelekomcloud/gophertelekomcloud/openstack/rms/query" + th "github.com/opentelekomcloud/gophertelekomcloud/testhelper" +) + +func TestSpecificResourceTypeList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListSpecificOpts{} + resources, err := query.ListSpecificType( + client, + client.DomainID, + "ecs", + "cloudservers", + listOpts, + ) + th.AssertNoErr(t, err) + tools.AssertLengthGreaterThan(t, resources, 1) +} + +func TestRecorderResourceList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListRecordedOpts{} + resources, err := query.ListRecordedResources( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(resources)) +} + +func TestServicesList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListServicesOpts{} + resources, err := query.ListServices( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + tools.AssertLengthGreaterThan(t, resources, 1) +} + +func TestGetSpecificByIdResource(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListSpecificOpts{} + resources, err := query.ListSpecificType( + client, + client.DomainID, + "ecs", + "cloudservers", + listOpts, + ) + th.AssertNoErr(t, err) + if len(resources) != 0 { + res, err := query.GetResource( + client, + client.DomainID, + "ecs", + "cloudservers", + resources[0].ID, + ) + th.AssertNoErr(t, err) + th.AssertEquals(t, resources[0].ID, res.ID) + } +} + +func TestRecordedResourcesTagsList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListRecordedTagsOpts{} + resources, err := query.ListRecordedResourcesTags( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(resources)) +} + +func TestRecordedResourcesSummaryList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListRecordedSummaryOpts{} + resources, err := query.ListRecordedResourcesSummary( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + th.AssertEquals(t, 0, len(resources)) +} + +func TestAllResourcesList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListAllOpts{} + resources, err := query.ListAllResources( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + tools.AssertLengthGreaterThan(t, resources, 1) +} + +func TestAnyResourceById(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListAllOpts{} + resources, err := query.ListAllResources( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + if len(resources) != 0 { + res, err := query.GetAnyResource( + client, + client.DomainID, + resources[0].ID, + ) + th.AssertNoErr(t, err) + th.AssertEquals(t, resources[0].ID, res.ID) + } +} + +func TestGetTagsFromAnyResource(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListAllTagsOpts{} + tags, err := query.ListAllResourcesTags( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + tools.AssertLengthGreaterThan(t, tags, 1) +} + +func TestGetCountResources(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.CountOpts{} + count, err := query.GetCount( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + tools.PrintResource(t, count) +} + +func TestResourcesSummaryList(t *testing.T) { + client, err := clients.NewRMSClient() + th.AssertNoErr(t, err) + + listOpts := query.ListSummaryOpts{} + resources, err := query.ListResourcesSummary( + client, + client.DomainID, + listOpts, + ) + th.AssertNoErr(t, err) + tools.AssertLengthGreaterThan(t, resources, 1) +} diff --git a/acceptance/tools/tools.go b/acceptance/tools/tools.go index c08dfd192..c0610fb96 100644 --- a/acceptance/tools/tools.go +++ b/acceptance/tools/tools.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" mrand "math/rand" + "reflect" "strings" "testing" "time" @@ -97,3 +98,30 @@ func SetLastOctet(ip string, newLastOctet int) string { // Reassemble the IP address return strings.Join(parts, ".") } + +// logFatal is a helper function to log fatal errors during the test. +func logFatal(t *testing.T, message string) { + t.Helper() + t.Fatal(message) +} + +// AssertLengthGreaterThan checks if the length of the provided list is greater than the specified number. +// If the condition fails, it logs a fatal error and fails the test. +func AssertLengthGreaterThan(t *testing.T, list interface{}, threshold int) { + t.Helper() + + // Use reflection to get the length of the list + listValue := reflect.ValueOf(list) + + // Ensure the list is a slice or array + if listValue.Kind() != reflect.Slice && listValue.Kind() != reflect.Array { + logFatal(t, fmt.Sprintf("expected a slice or array, but got %s", listValue.Kind().String())) + return + } + + // Check if the length is greater than the threshold + listLen := listValue.Len() + if listLen <= threshold { + logFatal(t, fmt.Sprintf("expected length to be greater than %d, but got %d", threshold, listLen)) + } +} diff --git a/openstack/client.go b/openstack/client.go index 8f5a95705..ccea0f292 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -1002,3 +1002,7 @@ func NewEVPNServiceV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpt } return sc, nil } + +func NewRmsServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + return initClientOpts(client, eo, "rms") +} diff --git a/openstack/css/v1/clusters/Create.go b/openstack/css/v1/clusters/Create.go index 77db11e05..fb955f0d2 100644 --- a/openstack/css/v1/clusters/Create.go +++ b/openstack/css/v1/clusters/Create.go @@ -2,6 +2,7 @@ package clusters import ( "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" "github.com/opentelekomcloud/gophertelekomcloud/openstack/common/tags" ) @@ -94,7 +95,7 @@ type DiskEncryption struct { } func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*CreatedCluster, error) { - b, err := golangsdk.BuildRequestBody(opts, "cluster") + b, err := build.RequestBody(opts, "cluster") if err != nil { return nil, err } diff --git a/openstack/rms/query/GetAnyResource.go b/openstack/rms/query/GetAnyResource.go new file mode 100644 index 000000000..33c12a20d --- /dev/null +++ b/openstack/rms/query/GetAnyResource.go @@ -0,0 +1,20 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +func GetAnyResource(client *golangsdk.ServiceClient, domainId, id string) (*Resource, error) { + // GET /v1/resource-manager/domains/{domain_id}/all-resources/{resource_id} + raw, err := client.Get(client.ServiceURL( + "resource-manager", "domains", domainId, + "all-resources", id), nil, nil) + if err != nil { + return nil, err + } + + var res Resource + err = extract.Into(raw.Body, &res) + return &res, err +} diff --git a/openstack/rms/query/GetCount.go b/openstack/rms/query/GetCount.go new file mode 100644 index 000000000..e856aaa5b --- /dev/null +++ b/openstack/rms/query/GetCount.go @@ -0,0 +1,42 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type CountOpts struct { + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the project ID. + ProjectId string `q:"project_id"` + // Specifies the resource type + Type string `q:"type"` + // Specifies the resource ID. + Id string `q:"id"` + // Specifies the resource name. + Name string `q:"name"` + // Specifies tags. The format is key or key=value. + Tags []string `q:"tags"` +} + +func GetCount(client *golangsdk.ServiceClient, domainId string, opts CountOpts) (*int, error) { + // GET /v1/resource-manager/domains/{domain_id}/all-resources/count + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "all-resources", "count"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) + if err != nil { + return nil, err + } + + var res struct { + Count int `json:"total_count"` + } + err = extract.Into(raw.Body, &res) + return &res.Count, err +} diff --git a/openstack/rms/query/GetRecordedResource.go b/openstack/rms/query/GetRecordedResource.go new file mode 100644 index 000000000..9dc01e0fb --- /dev/null +++ b/openstack/rms/query/GetRecordedResource.go @@ -0,0 +1,20 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +func GetRecordedResource(client *golangsdk.ServiceClient, domainId, id string) (*Resource, error) { + // GET /v1/resource-manager/domains/{domain_id}/tracked-resources/{resource_id} + raw, err := client.Get(client.ServiceURL( + "resource-manager", "domains", domainId, + "tracked-resources", id), nil, nil) + if err != nil { + return nil, err + } + + var res Resource + err = extract.Into(raw.Body, &res) + return &res, err +} diff --git a/openstack/rms/query/GetResource.go b/openstack/rms/query/GetResource.go new file mode 100644 index 000000000..9ebb1267e --- /dev/null +++ b/openstack/rms/query/GetResource.go @@ -0,0 +1,20 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +func GetResource(client *golangsdk.ServiceClient, domainId, service, resourceType, id string) (*Resource, error) { + // GET /v1/resource-manager/domains/{domain_id}/provider/{provider}/type/{type}/resources/{resource_id} + raw, err := client.Get(client.ServiceURL( + "resource-manager", "domains", domainId, + "provider", service, "type", resourceType, "resources", id), nil, nil) + if err != nil { + return nil, err + } + + var res Resource + err = extract.Into(raw.Body, &res) + return &res, err +} diff --git a/openstack/rms/query/ListAllResources.go b/openstack/rms/query/ListAllResources.go new file mode 100644 index 000000000..f22d86d35 --- /dev/null +++ b/openstack/rms/query/ListAllResources.go @@ -0,0 +1,44 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListAllOpts struct { + // Specifies the maximum number of resources to return. + Limit *int `q:"limit"` + // Specifies the pagination parameter. + Marker string `q:"marker"` + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the resource type + Type string `q:"type"` + // Specifies the resource ID. + Id string `q:"id"` + // Specifies the resource name. + Name string `q:"name"` + // Specifies tags. The format is key or key=value. + Tags []string `q:"tags"` +} + +func ListAllResources(client *golangsdk.ServiceClient, domainId string, opts ListAllOpts) ([]Resource, error) { + // GET /v1/resource-manager/domains/{domain_id}/all-resources + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "all-resources"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return ResPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractResources(pages) +} diff --git a/openstack/rms/query/ListAllResourcesTags.go b/openstack/rms/query/ListAllResourcesTags.go new file mode 100644 index 000000000..dc51e55c3 --- /dev/null +++ b/openstack/rms/query/ListAllResourcesTags.go @@ -0,0 +1,36 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListAllTagsOpts struct { + // Specifies the maximum number of resources to return. + Limit *int `q:"limit"` + // Specifies the pagination parameter. + Marker string `q:"marker"` + // Specifies the name of the tag key. + Key string `q:"key"` +} + +func ListAllResourcesTags(client *golangsdk.ServiceClient, domainId string, opts ListAllTagsOpts) ([]Tag, error) { + // GET /v1/resource-manager/domains/{domain_id}/all-resources/tags + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "all-resources", "tags"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return TagsPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractTags(pages) +} diff --git a/openstack/rms/query/ListRecordeResourceTags.go b/openstack/rms/query/ListRecordeResourceTags.go new file mode 100644 index 000000000..6e88ba7aa --- /dev/null +++ b/openstack/rms/query/ListRecordeResourceTags.go @@ -0,0 +1,61 @@ +package query + +import ( + "bytes" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListRecordedTagsOpts struct { + // Specifies the maximum number of resources to return. + Limit *int `q:"limit"` + // Specifies the pagination parameter. + Marker string `q:"marker"` + // Specifies the name of the tag key. + Key string `q:"key"` + // Indicating whether deleted resources need to be returned. + // This parameter is set to false by default. + ResourceDeleted *bool `q:"resource_deleted"` +} + +func ListRecordedResourcesTags(client *golangsdk.ServiceClient, domainId string, opts ListRecordedTagsOpts) ([]Tag, error) { + // GET /v1/resource-manager/domains/{domain_id}/tracked-resources/tags + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "tracked-resources", "tags"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return TagsPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractTags(pages) +} + +type TagsPage struct { + pagination.NewSinglePageBase +} + +func ExtractTags(r pagination.NewPage) ([]Tag, error) { + var s struct { + Tags []Tag `json:"tags"` + } + err := extract.Into(bytes.NewReader((r.(TagsPage)).Body), &s) + return s.Tags, err +} + +type Tag struct { + // Specifies the tag key. + Key string `json:"key"` + // Specifies tag values. + Value []string `json:"value"` +} diff --git a/openstack/rms/query/ListRecordedResources.go b/openstack/rms/query/ListRecordedResources.go new file mode 100644 index 000000000..65b42c061 --- /dev/null +++ b/openstack/rms/query/ListRecordedResources.go @@ -0,0 +1,47 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListRecordedOpts struct { + // Specifies the maximum number of resources to return. + Limit *int `q:"limit"` + // Specifies the pagination parameter. + Marker string `q:"marker"` + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the resource type + Type string `q:"type"` + // Specifies the resource ID. + Id string `q:"id"` + // Specifies the resource name. + Name string `q:"name"` + // Specifies tags. The format is key or key=value. + Tags []string `q:"tags"` + // Indicating whether deleted resources need to be returned. + // This parameter is set to false by default. + ResourceDeleted *bool `q:"resource_deleted"` +} + +func ListRecordedResources(client *golangsdk.ServiceClient, domainId string, opts ListRecordedOpts) ([]Resource, error) { + // GET /v1/resource-manager/domains/{domain_id}/tracked-resources + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "tracked-resources"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return ResPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractResources(pages) +} diff --git a/openstack/rms/query/ListRecordedResourcesSummary.go b/openstack/rms/query/ListRecordedResourcesSummary.go new file mode 100644 index 000000000..7c7d0a219 --- /dev/null +++ b/openstack/rms/query/ListRecordedResourcesSummary.go @@ -0,0 +1,77 @@ +package query + +import ( + "bytes" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListRecordedSummaryOpts struct { + // Specifies the resource name. + Name string `q:"name"` + // Specifies the resource type + Type string `q:"type"` + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the project ID. + ProjectId string `q:"project_id"` + // Specifies tags. The format is key or key=value. + Tags []string `q:"tags"` + // Indicating whether deleted resources need to be returned. + // This parameter is set to false by default. + ResourceDeleted *bool `q:"resource_deleted"` +} + +func ListRecordedResourcesSummary(client *golangsdk.ServiceClient, domainId string, opts ListRecordedSummaryOpts) ([]Summary, error) { + // GET /v1/resource-manager/domains/{domain_id}/tracked-resources/summary + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "tracked-resources", "summary"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return SummaryPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractSummary(pages) +} + +type SummaryPage struct { + pagination.NewSinglePageBase +} + +func ExtractSummary(r pagination.NewPage) ([]Summary, error) { + var summaries []Summary + err := extract.Into(bytes.NewReader((r.(SummaryPage)).Body), &summaries) + return summaries, err +} + +type Summary struct { + // Specifies the cloud service name. + Provider string `json:"provider"` + // Specifies the resource type list. + Types []Types `json:"types"` +} + +type Types struct { + // Specifies the resource type. + Type string `json:"type"` + // Specifies the regions. + Regions []Regions `json:"regions"` +} + +type Regions struct { + // Specifies the region ID. + RegionId string `json:"region_id"` + // Specifies the number of resources of this type in the current region. + Count int `json:"count"` +} diff --git a/openstack/rms/query/ListResourcesSummary.go b/openstack/rms/query/ListResourcesSummary.go new file mode 100644 index 000000000..3215ad9e4 --- /dev/null +++ b/openstack/rms/query/ListResourcesSummary.go @@ -0,0 +1,40 @@ +package query + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListSummaryOpts struct { + // Specifies the resource name. + Name string `q:"name"` + // Specifies the resource type + Type string `q:"type"` + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the project ID. + ProjectId string `q:"project_id"` + // Specifies tags. The format is key or key=value. + Tags []string `q:"tags"` +} + +func ListResourcesSummary(client *golangsdk.ServiceClient, domainId string, opts ListSummaryOpts) ([]Summary, error) { + // GET /v1/resource-manager/domains/{domain_id}/all-resources/summary + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "all-resources", "summary"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return SummaryPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractSummary(pages) +} diff --git a/openstack/rms/query/ListServices.go b/openstack/rms/query/ListServices.go new file mode 100644 index 000000000..cbfc4c930 --- /dev/null +++ b/openstack/rms/query/ListServices.go @@ -0,0 +1,86 @@ +package query + +import ( + "bytes" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListServicesOpts struct { + // Specifies the number of records returned on each page during pagination query. + Limit *int `q:"limit"` + // Specifies the pagination offset. + Offset *int `q:"offset"` + // Specifies whether resources are collected by default. tracked indicates that resources are collected by default, + // and untracked indicates that resources are not collected by default. + Track string `q:"track"` +} + +func ListServices(client *golangsdk.ServiceClient, domainId string, opts ListServicesOpts) ([]Service, error) { + // GET /v1/resource-manager/domains/{domain_id}/providers + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "providers"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return ServicesPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractServices(pages) +} + +type ServicesPage struct { + pagination.NewSinglePageBase +} + +func ExtractServices(r pagination.NewPage) ([]Service, error) { + var s struct { + Services []Service `json:"resource_providers"` + } + err := extract.Into(bytes.NewReader((r.(ServicesPage)).Body), &s) + return s.Services, err +} + +type Service struct { + // Specifies the cloud service name. + ServiceName string `json:"provider"` + // Specifies the display name of the cloud service. + // You can set the language by configuring X-Language in the request header. + DisplayName string `json:"display_name"` + // Specifies the display name of the cloud service type. + // You can set the language by configuring X-Language in the request header. + CategoryDisplayName string `json:"category_display_name"` + // Specifies the resource type list. + ResourceTypes []ResourceTypes `json:"resource_types"` +} + +type ResourceTypes struct { + // Specifies the resource type. + Name string `json:"name"` + // Specifies the display name of the resource type. + DisplayName string `json:"display_name"` + // Specifies whether the resource is a global resource. + Global bool `json:"global"` + // Specifies the list of supported regions. + Regions []string `json:"regions"` + // Specifies the console endpoint ID. + ConsoleEndpointId string `json:"console_endpoint_id"` + // Specifies the URL of the resource list page on the console. + ConsoleListUrl string `json:"console_list_url"` + // Specifies the URL of the resource details page on the console. + ConsoleDetailUrl string `json:"console_detail_url"` + // Specifies whether resources are collected by default. + // tracked indicates that resources are collected by default, + // and untracked indicates that resources are not collected by default. + Track string `json:"track"` +} diff --git a/openstack/rms/query/ListSpecificType.go b/openstack/rms/query/ListSpecificType.go new file mode 100644 index 000000000..2f8306bd2 --- /dev/null +++ b/openstack/rms/query/ListSpecificType.go @@ -0,0 +1,85 @@ +package query + +import ( + "bytes" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" + "github.com/opentelekomcloud/gophertelekomcloud/pagination" +) + +type ListSpecificOpts struct { + // Specifies the number of records returned on each page during pagination query. + Limit *int `q:"limit"` + // Specifies the start flag for querying the current page. If this parameter is left blank, the first page is queried. + // The marker for querying the next page is the next_marker in the page_info object returned on the current page. + Marker string `q:"marker"` + // Specifies the region ID. + RegionId string `q:"region_id"` + // Specifies the tag. + Tag map[string]string `q:"tag"` +} + +func ListSpecificType(client *golangsdk.ServiceClient, domainId, service, resourceType string, opts ListSpecificOpts) ([]Resource, error) { + // GET /v1/resource-manager/domains/{domainId}/provider/{service}/type/{resourceType}/resources + url, err := golangsdk.NewURLBuilder(). + WithEndpoints("resource-manager", "domains", domainId, "provider", service, "type", resourceType, "resources"). + WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + pages, err := pagination.Pager{ + Client: client, + InitialURL: client.ServiceURL(url.String()), + CreatePage: func(r pagination.NewPageResult) pagination.NewPage { + return ResPage{NewSinglePageBase: pagination.NewSinglePageBase{NewPageResult: r}} + }, + }.NewAllPages() + if err != nil { + return nil, err + } + return ExtractResources(pages) +} + +type ResPage struct { + pagination.NewSinglePageBase +} + +func ExtractResources(r pagination.NewPage) ([]Resource, error) { + var s struct { + Resources []Resource `json:"resources"` + } + err := extract.Into(bytes.NewReader((r.(ResPage)).Body), &s) + return s.Resources, err +} + +type Resource struct { + // Specifies the resource ID. + ID string `json:"id"` + // Specifies the resource name. + Name string `json:"name"` + // Specifies the cloud service name. + Service string `json:"provider"` + // Specifies the resource type. + Type string `json:"type"` + // Specifies the region ID. + RegionId string `json:"region_id"` + // Specifies the project ID in IaaS OpenStack. + ProjectId string `json:"project_id"` + // Specifies the project name in IaaS OpenStack. + ProjectName string `json:"project_name"` + // Specifies the resource checksum. + Checksum string `json:"checksum"` + // Specifies the time when the resource was created. + CreatedAt string `json:"created"` + // Specifies the time when the resource was updated. + UpdatedAt string `json:"updated"` + // Specifies the status of a resource operation. + ProvisioningState string `json:"provisioning_state"` + // Resource state. The value can be normal or deleted. + State string `json:"state"` + // Specifies the resource tag. + Tags map[string]string `json:"tags"` + // Specifies the detailed properties of the resource. + Properties map[string]interface{} `json:"properties"` +}