Skip to content

Commit

Permalink
first instance livecycle implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sgmv committed Aug 2, 2024
1 parent 133ccf3 commit 5694b77
Show file tree
Hide file tree
Showing 32 changed files with 1,774 additions and 0 deletions.
11 changes: 11 additions & 0 deletions acceptance/clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,17 @@ func NewDmsV2Client() (*golangsdk.ServiceClient, error) {
})
}

// NewDmsV21Client returns authenticated DMS v2 client
func NewDmsV21Client() (*golangsdk.ServiceClient, error) {
cc, err := CloudAndClient()
if err != nil {
return nil, err
}
return openstack.NewDMSServiceV21(cc.ProviderClient, golangsdk.EndpointOpts{
Region: cc.RegionName,
})
}

// NewSwrV2Client returns authenticated SWR v2 client
func NewSwrV2Client() (client *golangsdk.ServiceClient, err error) {
cc, err := CloudAndClient()
Expand Down
249 changes: 249 additions & 0 deletions acceptance/openstack/dms/v2.1/instances_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
package v2

import (
"strconv"
"testing"

golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/openstack"
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/tools"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v2.1/availablezones"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v2.1/instances"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v2.1/products"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v2.1/topics"
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
)

const (
dmsEngine = "kafka"
dmsEngineVersion = "2.7"
dmsUser = "root"
dmsUserPassword = "5ecuredPa55w0rd!"

kafkaClusterSmall = "cluster.small"

dmsTargetStatus = "RUNNING"
)

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

listOpts := instances.ListOpts{}
dmsInstances, err := instances.List(client, listOpts)
th.AssertNoErr(t, err)
for _, val := range dmsInstances.Instances {
tools.PrintResource(t, val)
}
}

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

instanceID := createDmsInstance(t, client)
defer deleteDmsInstance(t, client, instanceID)

dmsInstance, err := instances.Get(client, instanceID)
th.AssertNoErr(t, err)
th.AssertEquals(t, "some interesting description", dmsInstance.Description)

err = instances.ChangePassword(client, instanceID, instances.PasswordOpts{
NewPassword: "5ecuredPa55w0rd!-not",
})
th.AssertNoErr(t, err)
t.Logf("DMSv2 Instance password updated")

// updateDMScrossVpc(t, client, instanceID)
dmsTopic := createTopic(t, client, instanceID)

err = updateDmsTopic(t, client, instanceID, dmsTopic)
th.AssertNoErr(t, err)
t.Logf("DMSv2 Topic updated")

listTopics, err := topics.List(client, instanceID)
th.AssertNoErr(t, err)
th.AssertEquals(t, listTopics.Topics[0].Name, dmsTopic)

getTopic, err := topics.Get(client, instanceID, dmsTopic)
th.AssertNoErr(t, err)
th.AssertEquals(t, dmsTopic, getTopic.Name)

delTopic := deleteTopic(t, client, instanceID, dmsTopic)
th.AssertEquals(t, delTopic.Topics[0].Name, dmsTopic)

updateDmsInstance(t, client, instanceID)
dmsInstance, err = instances.Get(client, instanceID)
th.AssertNoErr(t, err)
th.AssertEquals(t, "", dmsInstance.Description)
}

func createDmsInstance(t *testing.T, client *golangsdk.ServiceClient) string {
t.Logf("Attempting to create DMSv2 instance")
dmsName := tools.RandomString("dms-acc-", 8)

vpcID := clients.EnvOS.GetEnv("VPC_ID")
subnetID := clients.EnvOS.GetEnv("NETWORK_ID")
if vpcID == "" || subnetID == "" {
t.Skip("One of OS_VPC_ID or OS_NETWORK_ID env vars is missing but DMS test requires using existing network")
}

defaultSgID := openstack.DefaultSecurityGroup(t)
details := getDmsInstanceSpecification(t, client, dmsEngine)
if details == nil {
t.Fatalf("product type %s not found", kafkaClusterSmall)
}
az := getDmsInstanceAz(t, client)
minBroker, _ := strconv.Atoi(details.Properties.MinBroker)
storageSpace, _ := strconv.Atoi(details.Properties.MinStoragePerNode)
storageSpec := details.IOS[0].IOSpec

sslEnable := true

createOpts := instances.CreateOpts{
Name: dmsName,
Description: "some interesting description",
Engine: dmsEngine,
EngineVersion: dmsEngineVersion,
StorageSpace: storageSpace * 3,
StorageSpecCode: storageSpec,
BrokerNum: minBroker,
ArchType: details.ArchTypes[0],
AccessUser: dmsUser,
Password: dmsUserPassword,
VpcID: vpcID,
SecurityGroupID: defaultSgID,
SubnetID: subnetID,
AvailableZones: []string{az},
ProductID: details.ProductId,
SslEnable: &sslEnable,
}

dmsInstance, err := instances.Create(client, createOpts)
th.AssertNoErr(t, err)
err = waitForInstanceAvailable(client, 600, dmsInstance.InstanceID)
th.AssertNoErr(t, err)
t.Logf("DMSv2 instance successfully created: %s", dmsInstance.InstanceID)

return dmsInstance.InstanceID
}

func deleteDmsInstance(t *testing.T, client *golangsdk.ServiceClient, instanceID string) {
t.Logf("Attempting to delete DMSv2 instance: %s", instanceID)

err := instances.Delete(client, instanceID)
th.AssertNoErr(t, err)

err = waitForInstanceDelete(client, 600, instanceID)
th.AssertNoErr(t, err)
t.Logf("DMSv1 instance deleted successfully: %s", instanceID)
}

func updateDmsInstance(t *testing.T, client *golangsdk.ServiceClient, instanceID string) {
t.Logf("Attempting to update DMSv2 instance: %s", instanceID)

emptyDescription := ""
updateOpts := instances.UpdateOpts{
Description: &emptyDescription,
}

err := instances.Update(client, instanceID, updateOpts)
th.AssertNoErr(t, err)

t.Logf("DMSv2 instance updated successfully: %s", instanceID)
}

func getDmsInstanceSpecification(t *testing.T, client *golangsdk.ServiceClient, engine string) *products.EngineProduct {
pd, err := products.Get(client, engine)
th.AssertNoErr(t, err)

for _, v := range pd.Products {
if v.Type == kafkaClusterSmall {
return &v
}
}

return nil
}

func getDmsInstanceAz(t *testing.T, client *golangsdk.ServiceClient) string {
az, err := availablezones.Get(client)
th.AssertNoErr(t, err)

return az.AvailableZones[0].ID
}

func waitForInstanceAvailable(client *golangsdk.ServiceClient, secs int, instanceID string) error {
return golangsdk.WaitFor(secs, func() (bool, error) {
dmsInstance, err := instances.Get(client, instanceID)
if err != nil {
return false, err
}
if dmsInstance.Status == dmsTargetStatus {
return true, nil
}
return false, nil
})
}

func waitForInstanceDelete(client *golangsdk.ServiceClient, secs int, instanceID string) error {
return golangsdk.WaitFor(secs, func() (bool, error) {
_, err := instances.Get(client, instanceID)
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
return true, nil
}
return false, err
}
return false, nil
})
}

func createTopic(t *testing.T, client *golangsdk.ServiceClient, instanceId string) string {
t.Logf("Attempting to create DMSv2 Topic")
topicName := tools.RandomString("dms-topic-", 8)

createOpts := topics.CreateOpts{
Name: topicName,
Partition: 10,
Replication: 2,
SyncReplication: true,
RetentionTime: 100,
SyncMessageFlush: true,
}
dmsTopic, err := topics.Create(client, instanceId, createOpts)
th.AssertNoErr(t, err)
t.Logf("DMSv2 Topic successfully created: %s", dmsTopic.Name)

return dmsTopic.Name
}

func updateDmsTopic(t *testing.T, client *golangsdk.ServiceClient, instanceId string, topicName string) error {
t.Logf("Attempting to update DMSv2 Topic")
partition := 12
retention := 70
updateOpts := topics.UpdateOpts{
Topics: []topics.UpdateItem{
{
Name: topicName,
Partition: &partition,
RetentionTime: &retention,
},
},
}
return topics.Update(client, instanceId, updateOpts)
}

func deleteTopic(t *testing.T, client *golangsdk.ServiceClient, instanceId string, name string) *topics.DeleteResponse {
t.Logf("Attempting to delete DMSv2 Topic")
dmsTopic, err := topics.Delete(client, instanceId, []string{
name,
})
th.AssertNoErr(t, err)
th.AssertEquals(t, true, dmsTopic.Topics[0].Success)

t.Logf("DMSv2 Topic successfully deleted")

return dmsTopic
}
77 changes: 77 additions & 0 deletions acceptance/openstack/dms/v2.1/users_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package v2

import (
"testing"

"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
"github.com/opentelekomcloud/gophertelekomcloud/acceptance/tools"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v1/permissions"
"github.com/opentelekomcloud/gophertelekomcloud/openstack/dms/v2/users"
th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
)

func TestUsersList(t *testing.T) {
t.Skip("DMS Creation takes too long to complete")
client, err := clients.NewDmsV2Client()
th.AssertNoErr(t, err)

instanceID := createDmsInstance(t, client)
defer deleteDmsInstance(t, client, instanceID)

dmsUsers, err := users.List(client, instanceID)
th.AssertNoErr(t, err)
for _, val := range dmsUsers {
tools.PrintResource(t, val)
}
}

func TestUsersLifecycle(t *testing.T) {
t.Skip("DMS Creation takes too long to complete")
client, err := clients.NewDmsV2Client()
th.AssertNoErr(t, err)
clientDmsV1, err := clients.NewDmsV11Client()
th.AssertNoErr(t, err)

instanceID := createDmsInstance(t, client)
defer deleteDmsInstance(t, client, instanceID)

dmsTopic := createTopic(t, client, instanceID)
defer deleteTopic(t, client, instanceID, dmsTopic)

userName := tools.RandomString("user", 5)

createOpts := users.CreateOpts{
UserName: userName,
UserPasswd: "test12312!",
}
err = users.Create(client, instanceID, createOpts)
th.AssertNoErr(t, err)

err = users.ResetPassword(client, instanceID, userName, "tes!$%t12312")
th.AssertNoErr(t, err)

err = permissions.Create(clientDmsV1, instanceID, []permissions.CreateOpts{{
Name: dmsTopic,
Policies: []permissions.CreatePolicy{
{
UserName: userName,
AccessPolicy: "all",
},
},
},
})

th.AssertNoErr(t, err)

userPermissions, err := permissions.List(clientDmsV1, instanceID, dmsTopic)
th.AssertNoErr(t, err)
tools.PrintResource(t, userPermissions)

err = users.Delete(client, instanceID, users.DeleteOpts{
Action: "delete",
Users: []string{
userName,
},
})
th.AssertNoErr(t, err)
}
5 changes: 5 additions & 0 deletions openstack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,11 @@ func NewDMSServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts
return initClientOpts(client, eo, "dmsv2")
}

// NewDMSServiceV21 creates a ServiceClient that may be used to access the v2 Distributed Message Service.
func NewDMSServiceV21(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
return initClientOpts(client, eo, "dmsv2")
}

// NewDCSServiceV1 creates a ServiceClient that may be used to access the v1 Distributed Cache Service.
func NewDCSServiceV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) {
return initClientOpts(client, eo, "dcsv1")
Expand Down
17 changes: 17 additions & 0 deletions openstack/dms/v2.1/availablezones/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package availablezones

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

// Get available zones
func Get(client *golangsdk.ServiceClient) (*GetResponse, error) {
raw, err := client.Get(getURL(client), nil, nil)
if err != nil {
return nil, err
}
var res GetResponse
err = extract.Into(raw.Body, &res)
return &res, err
}
20 changes: 20 additions & 0 deletions openstack/dms/v2.1/availablezones/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package availablezones

// GetResponse response
type GetResponse struct {
RegionID string `json:"regionId"`
AvailableZones []AvailableZone `json:"available_zones"`
}

// AvailableZone for dms
type AvailableZone struct {
ID string `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Port string `json:"port"`
ResourceAvailability string `json:"resource_availability"`
SoldOut bool `json:"soldOut"`
DefaultAz bool `json:"default_az"`
RemainTime uint64 `json:"remain_time"`
Ipv6Enable bool `json:"ipv6_enable"`
}
Loading

0 comments on commit 5694b77

Please sign in to comment.