-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first instance livecycle implementation
- Loading branch information
Showing
32 changed files
with
1,774 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"` | ||
} |
Oops, something went wrong.