Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat.] CBR update and refactoring #714

Merged
merged 5 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 87 additions & 4 deletions acceptance/openstack/cbr/v3/backups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

func TestBackupLifecycle(t *testing.T) {
if os.Getenv("RUN_CBR") == "" {
t.Skip("unstable test")
t.Skip("too long to run in ci")
}
client, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)
Expand Down Expand Up @@ -51,9 +51,6 @@ func TestBackupLifecycle(t *testing.T) {
}

func TestBackupListing(t *testing.T) {
if os.Getenv("RUN_CBR") == "" {
t.Skip("unstable test")
}
client, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)

Expand Down Expand Up @@ -136,3 +133,89 @@ func TestBackupListing(t *testing.T) {
th.AssertNoErr(t, errBack)
th.AssertNoErr(t, waitForBackupDelete(client, 600, allBackups[0].ID))
}

func TestBackupSharingLifecycle(t *testing.T) {
if os.Getenv("RUN_CBR") == "" {
t.Skip("too long to run in ci")
}
destProjectID := os.Getenv("OS_PROJECT_ID_2")
if destProjectID == "" {
t.Skip("OS_PROJECT_ID_2 are mandatory for this test!")
}
client, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)

vault, aOpts, optsVault, checkp := CreateCBR(t, client)
th.AssertEquals(t, vault.ID, checkp.Vault.ID)
th.AssertEquals(t, optsVault.Parameters.Description, checkp.ExtraInfo.Description)
th.AssertEquals(t, optsVault.Parameters.Name, checkp.ExtraInfo.Name)
th.AssertEquals(t, aOpts.Resources[0].Type, checkp.Vault.Resources[0].Type)

checkpointGet, err := checkpoint.Get(client, checkp.ID)
th.AssertNoErr(t, err)
th.AssertEquals(t, "available", checkpointGet.Status)
th.AssertEquals(t, vault.ID, checkpointGet.Vault.ID)
th.AssertEquals(t, aOpts.Resources[0].Type, checkp.Vault.Resources[0].Type)

allBackups, err := backups.List(client, backups.ListOpts{VaultID: vault.ID})
th.AssertNoErr(t, err)
t.Cleanup(func() {
err = backups.Delete(client, allBackups[0].ID)
th.AssertNoErr(t, err)
th.AssertNoErr(t, waitForBackupDelete(client, 600, allBackups[0].ID))
})

member, err := backups.AddSharingMember(client, allBackups[0].ID, backups.MembersOpts{
Members: []string{destProjectID},
})
th.AssertNoErr(t, err)
th.AssertEquals(t, member[0].DestProjectId, destProjectID)

members, err := backups.ListSharingMembers(client, allBackups[0].ID, backups.ListMemberOpts{})
th.AssertNoErr(t, err)
th.AssertEquals(t, 1, len(members))

t.Cleanup(func() {
err = backups.DeleteSharingMember(client, allBackups[0].ID, destProjectID)
th.AssertNoErr(t, err)
})

newCloud := os.Getenv("OS_CLOUD_2")
if newCloud != "" {
err = os.Setenv("OS_CLOUD", newCloud)
th.AssertNoErr(t, err)
_, err := clients.EnvOS.Cloud(newCloud)
th.AssertNoErr(t, err)
newClient, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)

// Create Vault for further accept member
vault2Opts := vaults.CreateOpts{
Billing: &vaults.BillingCreate{
ConsistentLevel: "crash_consistent",
ObjectType: "disk",
ProtectType: "backup",
Size: 100,
},
Description: "gophertelemocloud testing vault",
Name: tools.RandomString("cbr-test-", 5),
Resources: []vaults.ResourceCreate{},
}
vault2, err := vaults.Create(client, vault2Opts)
th.AssertNoErr(t, err)
t.Cleanup(func() {
th.AssertNoErr(t, vaults.Delete(client, vault2.ID))
})

_, err = backups.UpdateSharingMember(newClient, destProjectID, backups.UpdateOpts{
BackupID: allBackups[0].ID,
Status: "accepted",
VaultId: vault2.ID,
})
th.AssertNoErr(t, err)

newShare, err := backups.GetSharingMember(client, allBackups[0].ID, destProjectID)
th.AssertNoErr(t, err)
th.AssertEquals(t, "accepted", newShare.Status)
}
}
66 changes: 66 additions & 0 deletions acceptance/openstack/cbr/v3/policies_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v3

import (
"os"
"testing"

"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
Expand Down Expand Up @@ -66,3 +67,68 @@ func TestPolicyLifecycle(t *testing.T) {
th.CheckEquals(t, updateOpts.Name, current.Name)

}

func TestPolicyReplicationLifecycle(t *testing.T) {
destProjectID := os.Getenv("OS_PROJECT_ID_2")
destRegionName := os.Getenv("OS_REGION_NAME_2")
if destProjectID == "" || destRegionName == "" {
t.Skip("OS_PROJECT_ID_2 and OS_REGION_NAME_2 are mandatory for this test!")
}
client, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)
iTrue := true
policy, err := policies.Create(client, policies.CreateOpts{
Name: "test-policy",
OperationDefinition: &policies.PolicyODCreate{
DailyBackups: 1,
WeekBackups: 2,
YearBackups: 3,
MonthBackups: 4,
MaxBackups: 10,
Timezone: "UTC+03:00",
DestinationProjectId: destProjectID,
DestinationRegion: destRegionName,
},
Trigger: &policies.Trigger{
Properties: policies.TriggerProperties{
Pattern: []string{"FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;BYHOUR=14;BYMINUTE=00"},
},
},
Enabled: &iTrue,
OperationType: "replication",
})
th.AssertNoErr(t, err)

t.Cleanup(func() {
err = policies.Delete(client, policy.ID)
th.AssertNoErr(t, err)
})

allPolicies, err := policies.List(client, policies.ListOpts{})
th.AssertNoErr(t, err)
found := false
for _, p := range allPolicies {
if p.ID == policy.ID {
found = true
break
}
}
th.CheckEquals(t, true, found)

iFalse := false
updateOpts := policies.UpdateOpts{
Enabled: &iFalse,
Name: "name2",
}

updated, err := policies.Update(client, policy.ID, updateOpts)
th.AssertNoErr(t, err)
th.CheckEquals(t, *updateOpts.Enabled, updated.Enabled)
th.CheckEquals(t, updateOpts.Name, updated.Name)

current, err := policies.Get(client, policy.ID)
th.AssertNoErr(t, err)
th.CheckEquals(t, *updateOpts.Enabled, current.Enabled)
th.CheckEquals(t, updateOpts.Name, current.Name)

}
68 changes: 68 additions & 0 deletions acceptance/openstack/cbr/v3/vaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,71 @@ func TestVaultPolicy(t *testing.T) {
th.AssertEquals(t, vault.ID, unbind.VaultID)
th.AssertEquals(t, policy.ID, unbind.PolicyID)
}

func TestVaultMigrateResources(t *testing.T) {
client, err := clients.NewCbrV3Client()
th.AssertNoErr(t, err)

opts := vaults.CreateOpts{
Billing: &vaults.BillingCreate{
ConsistentLevel: "crash_consistent",
ObjectType: "disk",
ProtectType: "backup",
Size: 100,
},
Description: "gophertelemocloud testing vault",
Name: tools.RandomString("cbr-test-", 5),
Resources: []vaults.ResourceCreate{},
}
vault, err := vaults.Create(client, opts)
th.AssertNoErr(t, err)

t.Cleanup(func() {
th.AssertNoErr(t, vaults.Delete(client, vault.ID))
})

optsM := vaults.CreateOpts{
Billing: &vaults.BillingCreate{
ConsistentLevel: "crash_consistent",
ObjectType: "disk",
ProtectType: "backup",
Size: 100,
},
Description: "gophertelemocloud testing vault",
Name: tools.RandomString("cbr-test-migrate", 5),
Resources: []vaults.ResourceCreate{},
}
vaultM, err := vaults.Create(client, optsM)
th.AssertNoErr(t, err)

t.Cleanup(func() {
th.AssertNoErr(t, vaults.Delete(client, vaultM.ID))
})

resourceType := "OS::Cinder::Volume"
volume := openstack.CreateVolume(t)
t.Cleanup(func() {
openstack.DeleteVolume(t, volume.ID)
})

aOpts := vaults.AssociateResourcesOpts{
Resources: []vaults.ResourceCreate{
{
ID: volume.ID,
Type: resourceType,
Name: "cbr-vault-test-volume",
},
},
}
associated, err := vaults.AssociateResources(client, vault.ID, aOpts)
th.AssertNoErr(t, err)
th.AssertEquals(t, 1, len(associated))
th.AssertEquals(t, volume.ID, associated[0])

migrate, err := vaults.MigrateResources(client, vault.ID, vaults.MigrateOpts{
DestinationVaultId: vaultM.ID,
ResourceIds: associated,
})
th.AssertNoErr(t, err)
th.AssertEquals(t, 1, len(migrate))
}
4 changes: 2 additions & 2 deletions acceptance/openstack/rds/v3/flavors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestFlavorsList(t *testing.T) {

listOpts := flavors.ListOpts{
DatabaseName: "PostgreSQL",
VersionName: "10",
VersionName: "16",
}

rdsFlavors, err := flavors.ListFlavors(client, listOpts)
Expand All @@ -28,7 +28,7 @@ func TestFlavorsList(t *testing.T) {

storageTypes, err := flavors.ListStorageTypes(client, flavors.ListStorageTypesOpts{
DatabaseName: "PostgreSQL",
VersionName: "12",
VersionName: "16",
})
th.AssertNoErr(t, err)
tools.PrintResource(t, storageTypes)
Expand Down
49 changes: 49 additions & 0 deletions openstack/cbr/v3/backups/AddSharingMember.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package backups

import (
"github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/build"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

type MembersOpts struct {
// Project IDs of the backup share members to be added
Members []string `json:"members" required:"true"`
}

func AddSharingMember(client *golangsdk.ServiceClient, backupID string, opts MembersOpts) ([]Members, error) {
b, err := build.RequestBody(opts, "")
if err != nil {
return nil, err
}

// POST /v3/{project_id}/backups/{backup_id}/members
raw, err := client.Post(client.ServiceURL("backups", backupID, "members"), b, nil, &golangsdk.RequestOpts{
OkCodes: []int{200},
})
if err != nil {
return nil, err
}
var res []Members
err = extract.IntoSlicePtr(raw.Body, &res, "members")
return res, err
}

type Members struct {
// Backup sharing status
Status string `json:"status"`
// Backup sharing time
CreatedAt string `json:"created_at"`
// Update time
UpdatedAt string `json:"updated_at"`
// Backup ID
BackupId string `json:"backup_id"`
// ID of the image created by using the accepted shared backup
ImageId string `json:"image_id"`
// ID of the project with which the backup is shared
DestProjectId string `json:"dest_project_id"`
// Replication record ID
VaultId string `json:"vault_id"`
// ID of the shared record
ID string `json:"id"`
}
8 changes: 8 additions & 0 deletions openstack/cbr/v3/backups/DeleteSharingMember.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package backups

import "github.com/opentelekomcloud/gophertelekomcloud"

func DeleteSharingMember(client *golangsdk.ServiceClient, id, memberID string) (err error) {
_, err = client.Delete(client.ServiceURL("backups", id, "members", memberID), nil)
return
}
File renamed without changes.
17 changes: 17 additions & 0 deletions openstack/cbr/v3/backups/GetMember.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package backups

import (
"github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/internal/extract"
)

func GetSharingMember(client *golangsdk.ServiceClient, id, memberID string) (*Member, error) {
raw, err := client.Get(client.ServiceURL("backups", id, "members", memberID), nil, nil)
if err != nil {
return nil, err
}

var res Member
err = extract.IntoStructPtr(raw.Body, &res, "member")
return &res, err
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,27 @@ import (
// the API. Filtering is achieved by passing in struct field values that map to
// the flavor attributes you want to see returned.
type ListOpts struct {
ID string
CheckpointID string `q:"checkpoint_id"`
ImageType string `q:"image_type"`
Limit string `q:"limit"`
Marker string `q:"marker"`
Name string `q:"name"`
Offset string `q:"offset"`
ParentID string `q:"parent_id"`
ResourceAZ string `q:"resource_az"`
ResourceID string `q:"resource_id"`
ResourceName string `q:"resource_name"`
ResourceType string `q:"resource_type"`
Sort string `q:"sort"`
Status string `q:"status"`
VaultID string `q:"vault_id"`
ID string
CheckpointID string `q:"checkpoint_id"`
DedicatedCloud bool `q:"dec"`
EndTime string `q:"end_time"`
ImageType string `q:"image_type"`
Limit string `q:"limit"`
Marker string `q:"marker"`
MemberStatus string `q:"member_status"`
Name string `q:"name"`
Offset string `q:"offset"`
OwningType string `q:"own_type"`
ParentID string `q:"parent_id"`
ResourceAZ string `q:"resource_az"`
ResourceID string `q:"resource_id"`
ResourceName string `q:"resource_name"`
ResourceType string `q:"resource_type"`
Sort string `q:"sort"`
StartTime string `q:"start_time"`
Status string `q:"status"`
UsedPercent string `q:"used_percent"`
VaultID string `q:"vault_id"`
}

func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Backup, error) {
Expand Down
Loading