diff --git a/openstack/cbr/v3/vaults/requests.go b/openstack/cbr/v3/vaults/requests.go new file mode 100644 index 00000000..2f3b6c2c --- /dev/null +++ b/openstack/cbr/v3/vaults/requests.go @@ -0,0 +1,255 @@ +package vaults + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +type CreateOpts struct { + Billing *BillingCreate `json:"billing" required:"true"` + Name string `json:"name" required:"true"` + Resources []ResourceCreate `json:"resources" required:"true"` + AutoBind bool `json:"auto_bind,omitempty"` + AutoExpand bool `json:"auto_expand,omitempty"` + BackupPolicyID string `json:"backup_policy_id,omitempty"` + BindRules *VaultBindRules `json:"bind_rules,omitempty"` + Description string `json:"description,omitempty"` + EnterpriseProjectID string `json:"enterprise_project_id,omitempty"` + Tags []Tag `json:"tags,omitempty"` +} + +type BillingCreate struct { + ConsistentLevel string `json:"consistent_level" required:"true"` + ObjectType string `json:"object_type" required:"true"` + ProtectType string `json:"protect_type" required:"true"` + Size int `json:"size" required:"true"` + ChargingMode string `json:"charging_mode,omitempty"` + CloudType string `json:"cloud_type,omitempty"` + ConsoleURL string `json:"console_url,omitempty"` + ExtraInfo *BillingCreateExtraInfo `json:"extra_info,omitempty"` + PeriodNum int `json:"period_num,omitempty"` + PeriodType string `json:"period_type,omitempty"` + IsAutoRenew bool `json:"is_auto_renew,omitempty"` + IsAutoPay bool `json:"is_auto_pay,omitempty"` +} + +type BillingCreateExtraInfo struct { + CombinedOrderECSNum int `json:"combined_order_ecs_num,omitempty"` + CombinedOrderID string `json:"combined_order_id,omitempty"` +} + +type ResourceCreate struct { + ID string `json:"id" required:"true"` + Type string `json:"type" required:"true"` + Name string `json:"name,omitempty"` + ExtraInfo *ResourceExtraInfo `json:"extra_info,omitempty"` +} + +type ResourceExtraInfo struct { + ExcludeVolumes []string `json:"exclude_volumes,omitempty"` + IncludeVolumes []ResourceExtraInfoIncludeVolumes `json:"include_volumes,omitempty"` +} + +type ResourceExtraInfoIncludeVolumes struct { + ID string `json:"id" required:"true"` + OSVersion string `json:"os_version,omitempty"` +} + +type VaultBindRules struct { + Tags []Tag `json:"tags,omitempty"` +} + +type Tag struct { + Key string `json:"key" required:"true"` + Value string `json:"value,omitempty"` +} + +type CreateOptsBuilder interface { + ToVaultCreateMap() (map[string]interface{}, error) +} + +func (opts CreateOpts) ToVaultCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "vault") +} + +func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + reqBody, err := opts.ToVaultCreateMap() + if err != nil { + r.Err = err + return + } + _, err = client.Post(rootURL(client), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + r.Err = err + return +} + +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(resourceURL(client, id), nil) + return +} + +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(resourceURL(client, id), &r.Body, nil) + return +} + +type UpdateOpts struct { + Billing *BillingUpdate `json:"billing,omitempty"` + Name string `json:"name,omitempty"` + AutoBind *bool `json:"auto_bind,omitempty"` + BindRules *VaultBindRules `json:"bind_rules,omitempty"` + AutoExpand *bool `json:"auto_expand,omitempty"` +} + +type BillingUpdate struct { + Size int `json:"size,omitempty"` +} + +type UpdateOptsBuilder interface { + ToVaultUpdateMap() (map[string]interface{}, error) +} + +func (opts UpdateOpts) ToVaultUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "vault") +} + +func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + reqBody, err := opts.ToVaultUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(resourceURL(client, id), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +type ListOpts struct { + CloudType string `q:"cloud_type"` + EnterpriseProjectID string `q:"enterprise_project_id"` + ID string `q:"id"` + Limit string `q:"limit"` + Name string `q:"name"` + ObjectType string `q:"object_type"` + Offset string `q:"offset"` + PolicyID string `q:"policy_id"` + ProtectType string `q:"protect_type"` + ResourceIDs string `q:"resource_ids"` + Status string `q:"status"` +} + +func (opts ListOpts) ToPolicyListQuery() (string, error) { + q, err := golangsdk.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), err +} + +type ListOptsBuilder interface { + ToPolicyListQuery() (string, error) +} + +//List is a method to obtain the specified CBR vaults according to the vault ID, vault name and so on. +//This method can also obtain all the CBR vaults through the default parameter settings. +func List(client *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := rootURL(client) + if opts != nil { + query, err := opts.ToPolicyListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return VaultPage{pagination.SinglePageBase(r)} + }) +} + +type BindPolicyOpts struct { + PolicyID string `json:"policy_id" required:"true"` +} + +func (opts BindPolicyOpts) ToBindPolicyMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +type BindPolicyOptsBuilder interface { + ToBindPolicyMap() (map[string]interface{}, error) +} + +func BindPolicy(client *golangsdk.ServiceClient, vaultID string, opts BindPolicyOptsBuilder) (r BindPolicyResult) { + reqBody, err := opts.ToBindPolicyMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(bindPolicyURL(client, vaultID), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +func UnbindPolicy(client *golangsdk.ServiceClient, vaultID string, opts BindPolicyOptsBuilder) (r UnbindPolicyResult) { + reqBody, err := opts.ToBindPolicyMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(unbindPolicyURL(client, vaultID), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +type AssociateResourcesOpts struct { + Resources []ResourceCreate `json:"resources" required:"true"` +} + +func (opts AssociateResourcesOpts) ToAssociateResourcesMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +type AssociateResourcesOptsBuilder interface { + ToAssociateResourcesMap() (map[string]interface{}, error) +} + +func AssociateResources(client *golangsdk.ServiceClient, vaultID string, opts AssociateResourcesOptsBuilder) (r AssociateResourcesResult) { + reqBody, err := opts.ToAssociateResourcesMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(addResourcesURL(client, vaultID), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +type DissociateResourcesOpts struct { + ResourceIDs []string `json:"resource_ids" required:"true"` +} + +func (opts DissociateResourcesOpts) ToDissociateResourcesMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +type DissociateResourcesOptsBuilder interface { + ToDissociateResourcesMap() (map[string]interface{}, error) +} + +func DissociateResources(client *golangsdk.ServiceClient, vaultID string, opts DissociateResourcesOptsBuilder) (r DissociateResourcesResult) { + reqBody, err := opts.ToDissociateResourcesMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(removeResourcesURL(client, vaultID), reqBody, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} diff --git a/openstack/cbr/v3/vaults/results.go b/openstack/cbr/v3/vaults/results.go new file mode 100644 index 00000000..d18eeb1c --- /dev/null +++ b/openstack/cbr/v3/vaults/results.go @@ -0,0 +1,158 @@ +package vaults + +import ( + "fmt" + + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +type commonResult struct { + golangsdk.Result +} + +type CreateResult struct { + commonResult +} + +type GetResult struct { + commonResult +} + +type UpdateResult struct { + commonResult +} + +type DeleteResult struct { + golangsdk.ErrResult +} + +type Vault struct { + ID string `json:"id"` + Name string `json:"name"` + Billing Billing `json:"billing"` + Description string `json:"description"` + ProjectID string `json:"project_id"` + ProviderID string `json:"provider_id"` + Resources []ResourceResp `json:"resources"` + Tags []Tag `json:"tags"` + EnterpriseProjectID string `json:"enterprise_project_id"` + AutoBind bool `json:"auto_bind"` + BindRules VaultBindRules `json:"bind_rules"` + UserID string `json:"user_id"` + CreatedAt string `json:"created_at"` + AutoExpand bool `json:"auto_expand"` +} + +type Billing struct { + Allocated int `json:"allocated"` + ChargingMode string `json:"charging_mode"` + CloudType string `json:"cloud_type"` + ConsistentLevel string `json:"consistent_level"` + ObjectType string `json:"object_type"` + OrderID string `json:"order_id"` + ProductID string `json:"product_id"` + ProtectType string `json:"protect_type"` + Size int `json:"size"` + SpecCode string `json:"spec_code"` + Status string `json:"status"` + StorageUnit string `json:"storage_unit"` + Used int `json:"used"` + FrozenScene string `json:"frozen_scene"` +} + +type ResourceResp struct { + ExtraInfo ResourceExtraInfo `json:"extra_info"` + ID string `json:"id"` + Name string `json:"name"` + ProtectStatus string `json:"protect_status"` + Size int `json:"size"` + Type string `json:"type"` + BackupSize int `json:"backup_size"` + BackupCount int `json:"backup_count"` +} + +func (r commonResult) Extract() (*Vault, error) { + var s struct { + Vault *Vault `json:"vault"` + } + err := r.ExtractInto(&s) + return s.Vault, err +} + +type AssociateResourcesResult struct { + golangsdk.Result +} + +func (r AssociateResourcesResult) Extract() ([]string, error) { + var s struct { + AddResourceIDs []string `json:"add_resource_ids"` + } + if r.Err != nil { + return nil, r.Err + } + err := r.ExtractInto(&s) + if err != nil { + return nil, fmt.Errorf("failed to extract Associated Resource IDs") + } + return s.AddResourceIDs, nil +} + +type DissociateResourcesResult struct { + golangsdk.Result +} + +func (r DissociateResourcesResult) Extract() ([]string, error) { + var s struct { + RemoveResourceIDs []string `json:"remove_resource_ids"` + } + if r.Err != nil { + return nil, r.Err + } + err := r.ExtractInto(&s) + if err != nil { + return nil, fmt.Errorf("failed to extract Dissociated Resource IDs") + } + return s.RemoveResourceIDs, nil +} + +type BindPolicyResult struct { + golangsdk.Result +} + +type PolicyBinding struct { + VaultID string `json:"vault_id"` + PolicyID string `json:"policy_id"` +} + +func (r BindPolicyResult) Extract() (*PolicyBinding, error) { + var s struct { + PolicyBinding *PolicyBinding `json:"associate_policy"` + } + err := r.ExtractInto(&s) + return s.PolicyBinding, err +} + +type UnbindPolicyResult struct { + golangsdk.Result +} + +func (r UnbindPolicyResult) Extract() (*PolicyBinding, error) { + var s struct { + PolicyBinding *PolicyBinding `json:"dissociate_policy"` + } + err := r.ExtractInto(&s) + return s.PolicyBinding, err +} + +type VaultPage struct { + pagination.SinglePageBase +} + +func ExtractVaults(r pagination.Page) (*[]Vault, error) { + var s struct { + Vaults []Vault `json:"vaults"` + } + err := (r.(VaultPage)).ExtractInto(&s) + return &s.Vaults, err +} diff --git a/openstack/cbr/v3/vaults/testing/fixtures.go b/openstack/cbr/v3/vaults/testing/fixtures.go new file mode 100644 index 00000000..a203cdce --- /dev/null +++ b/openstack/cbr/v3/vaults/testing/fixtures.go @@ -0,0 +1,467 @@ +package testing + +import ( + "fmt" + "net/http" + "testing" + + "github.com/huaweicloud/golangsdk/openstack/cbr/v3/vaults" + th "github.com/huaweicloud/golangsdk/testhelper" + "github.com/huaweicloud/golangsdk/testhelper/client" +) + +const ( + expectedCreateRequest = ` +{ + "vault" : { + "backup_policy_id" : "6dd81d7d-a4cb-443e-b8ed-1af0bd3a261b", + "billing" : { + "cloud_type" : "public", + "consistent_level" : "crash_consistent", + "object_type" : "server", + "protect_type" : "backup", + "size" : 100, + "charging_mode" : "post_paid", + "console_url" : "https://console.demo.com/cbr/?agencyId=97fcd896b7914cb98f553a087232e243®ion=testregion/cbr/manager/csbs/vaultList" + }, + "description" : "vault_description", + "name" : "vault_name", + "resources" : [ { + "extra_info" : { + "include_volumes" : [ { + "id" : "73ee8446-bce7-4371-9650-b440b5f4c1d0", + "os_version" : "CentOS 7.6 64bit" + } ] + }, + "id" : "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + "type" : "OS::Nova::Server" + } ], + "tags" : [ { + "key" : "key01", + "value" : "value01" + } ], + "enterprise_project_id" : "0" + } +}` + expectedCreateResponse = ` +{ + "vault" : { + "provider_id" : "0daac4c5-6707-4851-97ba-169e36266b66", + "description" : "vault_description", + "tags" : [ { + "value" : "value01", + "key" : "key01" + } ], + "enterprise_project_id" : "0", + "auto_bind" : false, + "id" : "ad7627ae-5b0b-492e-b6bd-cd809b745197", + "user_id" : "38d65be2ecd840d19046e239e841a734", + "name" : "vault_name", + "billing" : { + "status" : "available", + "used" : 0, + "protect_type" : "backup", + "object_type" : "server", + "allocated" : 40, + "spec_code" : "vault.backup.server.normal", + "size" : 100, + "cloud_type" : "public", + "consistent_level" : "crash_consistent", + "charging_mode" : "post_paid" + }, + "created_at" : "2019-05-23T12:51:10.071232", + "project_id" : "fc347bc64ccd4589ae52e4f44b7433c7", + "resources" : [ { + "name" : "ecs-b977-0002", + "backup_size" : 0, + "protect_status" : "available", + "backup_count" : 0, + "extra_info" : { + "include_volumes" : [ { + "os_version" : "CentOS 7.6 64bit", + "id" : "73ee8446-bce7-4371-9650-b440b5f4c1d0" + } ] + }, + "type" : "OS::Nova::Server", + "id" : "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + "size" : 40 + } ] + } +}` + expectedUpdateRequest = ` +{ + "vault" : { + "billing" : { + "size" : 100 + }, + "name" : "vault_name" + } + } +}` + + expectedListResponse = ` +{ + "vaults" : [ { + "provider_id" : "0daac4c5-6707-4851-97ba-169e36266b66", + "description" : "vault_description", + "tags" : [ { + "value" : "value01", + "key" : "key01" + } ], + "enterprise_project_id" : "0", + "auto_bind" : false, + "id" : "ad7627ae-5b0b-492e-b6bd-cd809b745197", + "user_id" : "38d65be2ecd840d19046e239e841a734", + "name" : "vault_name", + "billing" : { + "status" : "available", + "used" : 0, + "protect_type" : "backup", + "object_type" : "server", + "allocated" : 40, + "spec_code" : "vault.backup.server.normal", + "size" : 100, + "cloud_type" : "public", + "consistent_level" : "crash_consistent", + "charging_mode" : "post_paid" + }, + "created_at" : "2019-05-23T12:51:10.071232", + "project_id" : "fc347bc64ccd4589ae52e4f44b7433c7", + "resources" : [ { + "name" : "ecs-b977-0002", + "backup_size" : 0, + "protect_status" : "available", + "backup_count" : 0, + "extra_info" : { + "include_volumes" : [ { + "os_version" : "CentOS 7.6 64bit", + "id" : "73ee8446-bce7-4371-9650-b440b5f4c1d0" + } ] + }, + "type" : "OS::Nova::Server", + "id" : "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + "size" : 40 + } ] + } ], + "count" : 1 +}` + + expectedPolicyBindingResponse = ` +{ + "associate_policy" : { + "vault_id" : "ad7627ae-5b0b-492e-b6bd-cd809b745197", + "policy_id" : "7075c397-25a0-43e2-a83a-bb16eaca3ee5" + } +}` + + expectedPolicyUnbindingResponse = ` +{ + "dissociate_policy" : { + "vault_id" : "ad7627ae-5b0b-492e-b6bd-cd809b745197", + "policy_id" : "7075c397-25a0-43e2-a83a-bb16eaca3ee5" + } +}` + + expectedAssociateResourcesRequest = ` +{ + "resources" : [ { + "extra_info" : { + "exclude_volumes" : [ "bdef09bb-293f-446a-88a4-86e9f14408c4" ] + }, + "id" : "97595625-198e-4e4d-879b-9d53f68ba551", + "type" : "OS::Nova::Server" + } ] +}` + + expectedAssociateResourcesResponse = ` +{ + "add_resource_ids" : [ "97595625-198e-4e4d-879b-9d53f68ba551" ] +}` + + expectedDissociateResourcesRequest = ` +{ + "resource_ids" : [ "97595625-198e-4e4d-879b-9d53f68ba551" ] +}` + + expectedDissociateResourcesResponse = ` +{ + "remove_resource_ids" : [ "fe578a6c-d1a8-4790-bd52-5954af4d446c" ] +}` + + expectedMigrateResourcesResponse = ` +{ + 'resource_ids': [ 'abcdde3f-e0e3-403a-b690-fc259dd70008' ], + 'destination_vault_id': 'fe578a6c-d1a8-4790-bd52-5954af4d446c' +}` +) + +var ( + createOpts = &vaults.CreateOpts{ + BackupPolicyID: "6dd81d7d-a4cb-443e-b8ed-1af0bd3a261b", + Billing: &vaults.BillingCreate{ + ConsistentLevel: "crash_consistent", + CloudType: "public", + ObjectType: "server", + ProtectType: "backup", + Size: 100, + ChargingMode: "post_paid", + ConsoleURL: "https://console.demo.com/cbr/?agencyId=97fcd896b7914cb98f553a087232e243®ion=testregion/cbr/manager/csbs/vaultList", + }, + Description: "vault_description", + EnterpriseProjectID: "0", + Name: "vault_name", + Resources: []vaults.ResourceCreate{ + { + ID: "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + Type: "OS::Nova::Server", + ExtraInfo: &vaults.ResourceExtraInfo{ + IncludeVolumes: []vaults.ResourceExtraInfoIncludeVolumes{ + { + ID: "73ee8446-bce7-4371-9650-b440b5f4c1d0", + OSVersion: "CentOS 7.6 64bit", + }, + }, + }, + }, + }, + Tags: []vaults.Tag{ + { + Key: "key01", + Value: "value01", + }, + }, + } + + expectedCreateResponseData = &vaults.Vault{ + ID: "ad7627ae-5b0b-492e-b6bd-cd809b745197", + Name: "vault_name", + UserID: "38d65be2ecd840d19046e239e841a734", + AutoBind: false, + ProviderID: "0daac4c5-6707-4851-97ba-169e36266b66", + ProjectID: "fc347bc64ccd4589ae52e4f44b7433c7", + Description: "vault_description", + EnterpriseProjectID: "0", + CreatedAt: "2019-05-23T12:51:10.071232", + Billing: vaults.Billing{ + Status: "available", + ProtectType: "backup", + ObjectType: "server", + SpecCode: "vault.backup.server.normal", + CloudType: "public", + ConsistentLevel: "crash_consistent", + ChargingMode: "post_paid", + Used: 0, + Allocated: 40, + Size: 100, + }, + Tags: []vaults.Tag{ + { + Key: "key01", + Value: "value01", + }, + }, + Resources: []vaults.ResourceResp{ + { + ID: "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + Type: "OS::Nova::Server", + Name: "ecs-b977-0002", + ProtectStatus: "available", + BackupSize: 0, + BackupCount: 0, + Size: 40, + ExtraInfo: vaults.ResourceExtraInfo{ + IncludeVolumes: []vaults.ResourceExtraInfoIncludeVolumes{ + { + ID: "73ee8446-bce7-4371-9650-b440b5f4c1d0", + OSVersion: "CentOS 7.6 64bit", + }, + }, + }, + }, + }, + } + + updateOpts = &vaults.UpdateOpts{ + Billing: &vaults.BillingUpdate{ + Size: 100, + }, + Name: "vault_name", + } + + expectedListResponseData = &[]vaults.Vault{ + { + ID: "ad7627ae-5b0b-492e-b6bd-cd809b745197", + Name: "vault_name", + UserID: "38d65be2ecd840d19046e239e841a734", + AutoBind: false, + ProviderID: "0daac4c5-6707-4851-97ba-169e36266b66", + ProjectID: "fc347bc64ccd4589ae52e4f44b7433c7", + Description: "vault_description", + EnterpriseProjectID: "0", + CreatedAt: "2019-05-23T12:51:10.071232", + Billing: vaults.Billing{ + Status: "available", + ProtectType: "backup", + ObjectType: "server", + SpecCode: "vault.backup.server.normal", + CloudType: "public", + ConsistentLevel: "crash_consistent", + ChargingMode: "post_paid", + Used: 0, + Allocated: 40, + Size: 100, + }, + Tags: []vaults.Tag{ + { + Key: "key01", + Value: "value01", + }, + }, + Resources: []vaults.ResourceResp{ + { + ID: "23a320a5-3efd-4568-b1aa-8dd9183cc64c", + Type: "OS::Nova::Server", + Name: "ecs-b977-0002", + ProtectStatus: "available", + BackupSize: 0, + BackupCount: 0, + Size: 40, + ExtraInfo: vaults.ResourceExtraInfo{ + IncludeVolumes: []vaults.ResourceExtraInfoIncludeVolumes{ + { + ID: "73ee8446-bce7-4371-9650-b440b5f4c1d0", + OSVersion: "CentOS 7.6 64bit", + }, + }, + }, + }, + }, + }, + } + + bindPolicyOpts = &vaults.BindPolicyOpts{ + PolicyID: "7075c397-25a0-43e2-a83a-bb16eaca3ee5", + } + + expectedPolicyBindingResponseData = &vaults.PolicyBinding{ + VaultID: "ad7627ae-5b0b-492e-b6bd-cd809b745197", + PolicyID: "7075c397-25a0-43e2-a83a-bb16eaca3ee5", + } + + associateResourcesOpts = &vaults.AssociateResourcesOpts{ + Resources: []vaults.ResourceCreate{ + { + ExtraInfo: &vaults.ResourceExtraInfo{ + ExcludeVolumes: []string{ + "bdef09bb-293f-446a-88a4-86e9f14408c4", + }, + }, + ID: "97595625-198e-4e4d-879b-9d53f68ba551", + Type: "OS::Nova::Server", + }, + }, + } + + expectedAssociateResourcesResponseData = []string{ + "97595625-198e-4e4d-879b-9d53f68ba551", + } + + dissociateResourcesOpts = &vaults.DissociateResourcesOpts{ + ResourceIDs: []string{ + "97595625-198e-4e4d-879b-9d53f68ba551", + }, + } +) + +func handleVaultCreate(t *testing.T) { + th.Mux.HandleFunc("/vaults", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, expectedCreateResponse) + }) +} + +func handleVaultGet(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedCreateResponse) + }) +} + +func handleVaultUpdate(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "PUT") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, expectedCreateResponse) + }) +} + +func handleVaultDelete(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "DELETE") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusNoContent) + }) +} + +func handleVaultList(t *testing.T) { + th.Mux.HandleFunc("/vaults", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedListResponse) + }) +} + +func handleVaultBindPolicy(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197/associatepolicy", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedPolicyBindingResponse) + }) +} + +func handleVaultUnbindPolicy(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197/dissociatepolicy", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedPolicyUnbindingResponse) + }) +} + +func handleVaultAssociateResources(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197/addresources", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedAssociateResourcesResponse) + }) +} + +func handleVaultDissociateResources(t *testing.T) { + th.Mux.HandleFunc("/vaults/ad7627ae-5b0b-492e-b6bd-cd809b745197/removeresources", + func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = fmt.Fprint(w, expectedAssociateResourcesResponse) + }) +} diff --git a/openstack/cbr/v3/vaults/testing/requests_test.go b/openstack/cbr/v3/vaults/testing/requests_test.go new file mode 100644 index 00000000..47fd9783 --- /dev/null +++ b/openstack/cbr/v3/vaults/testing/requests_test.go @@ -0,0 +1,109 @@ +package testing + +import ( + "testing" + + "github.com/huaweicloud/golangsdk/openstack/cbr/v3/vaults" + th "github.com/huaweicloud/golangsdk/testhelper" + "github.com/huaweicloud/golangsdk/testhelper/client" +) + +func TestCreateV3VaultsMarshall(t *testing.T) { + res, err := createOpts.ToVaultCreateMap() + th.AssertNoErr(t, err) + th.AssertJSONEquals(t, expectedCreateRequest, res) +} + +func TestCreateV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultCreate(t) + + actual, err := vaults.Create(client.ServiceClient(), createOpts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedCreateResponseData, actual) +} + +func TestGetV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultGet(t) + + actual, err := vaults.Get(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197").Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedCreateResponseData, actual) +} + +func TestUpdateV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultUpdate(t) + + actual, err := vaults.Update(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197", updateOpts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedCreateResponseData, actual) +} + +func TestDeleteV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultDelete(t) + + err := vaults.Delete(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197").ExtractErr() + th.AssertNoErr(t, err) +} + +func TestListV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultList(t) + + allPages, err := vaults.List(client.ServiceClient(), vaults.ListOpts{}).AllPages() + th.AssertNoErr(t, err) + actual, err := vaults.ExtractVaults(allPages) + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedListResponseData, actual) +} + +func TestPolicyBindingV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultBindPolicy(t) + + actual, err := vaults.BindPolicy(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197", + bindPolicyOpts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedPolicyBindingResponseData, actual) +} + +func TestPolicyUnbindingV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultUnbindPolicy(t) + + actual, err := vaults.UnbindPolicy(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197", + bindPolicyOpts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedPolicyBindingResponseData, actual) +} + +func TestAssociateResourcesV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultAssociateResources(t) + + actual, err := vaults.AssociateResources(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197", + associateResourcesOpts).Extract() + th.AssertNoErr(t, err) + th.AssertDeepEquals(t, expectedAssociateResourcesResponseData, actual) +} + +func TestDissociateResourcesV3Vault(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + handleVaultDissociateResources(t) + + _, err := vaults.DissociateResources(client.ServiceClient(), "ad7627ae-5b0b-492e-b6bd-cd809b745197", + dissociateResourcesOpts).Extract() + th.AssertNoErr(t, err) +} diff --git a/openstack/cbr/v3/vaults/urls.go b/openstack/cbr/v3/vaults/urls.go new file mode 100644 index 00000000..5f2df1ed --- /dev/null +++ b/openstack/cbr/v3/vaults/urls.go @@ -0,0 +1,33 @@ +package vaults + +import "github.com/huaweicloud/golangsdk" + +const resourcePath = "vaults" + +func rootURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} + +func resourceURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +func addResourcesURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id, "addresources") +} + +func removeResourcesURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id, "removeresources") +} + +func migrateResourcesURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id, "migrateresources") +} + +func bindPolicyURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id, "associatepolicy") +} + +func unbindPolicyURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id, "dissociatepolicy") +}