github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/acceptance/openstack/dds/v3/instances_test.go (about)

     1  package v3
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
     9  	"github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients"
    10  	"github.com/opentelekomcloud/gophertelekomcloud/acceptance/openstack"
    11  	networking "github.com/opentelekomcloud/gophertelekomcloud/acceptance/openstack/networking/v1"
    12  	"github.com/opentelekomcloud/gophertelekomcloud/acceptance/tools"
    13  	"github.com/opentelekomcloud/gophertelekomcloud/openstack/common/tags"
    14  	"github.com/opentelekomcloud/gophertelekomcloud/openstack/dds/v3/instances"
    15  	ddsjob "github.com/opentelekomcloud/gophertelekomcloud/openstack/dds/v3/job"
    16  	th "github.com/opentelekomcloud/gophertelekomcloud/testhelper"
    17  )
    18  
    19  func TestDdsList(t *testing.T) {
    20  	client, err := clients.NewDdsV3Client()
    21  	th.AssertNoErr(t, err)
    22  
    23  	listOpts := instances.ListInstanceOpts{}
    24  	_, err = instances.List(client, listOpts)
    25  	th.AssertNoErr(t, err)
    26  }
    27  
    28  func TestDdsSingleLifeCycle(t *testing.T) {
    29  	client, err := clients.NewDdsV3Client()
    30  	th.AssertNoErr(t, err)
    31  
    32  	t.Logf("Attempting to create DDSv3 single instance")
    33  	ddsInstance := createDdsSingleInstance(t, client)
    34  	defer deleteDdsInstance(t, client, ddsInstance.Id)
    35  
    36  	listOpts := instances.ListInstanceOpts{Id: ddsInstance.Id}
    37  	newDdsInstance, err := instances.List(client, listOpts)
    38  	th.AssertNoErr(t, err)
    39  	if newDdsInstance.TotalCount == 0 {
    40  		t.Fatalf("No DDSv3 instance was found: %s", err)
    41  	}
    42  	t.Log(newDdsInstance.Instances[0])
    43  	updateDdsInstance(t, client, newDdsInstance.Instances[0])
    44  }
    45  
    46  func TestDdsClusterLifeCycle(t *testing.T) {
    47  	client, err := clients.NewDdsV3Client()
    48  	th.AssertNoErr(t, err)
    49  
    50  	t.Logf("Attempting to create DDSv3 cluster instance")
    51  	ddsInstance := createDdsClusterInstance(t, client)
    52  	defer deleteDdsInstance(t, client, ddsInstance.Id)
    53  
    54  	listOpts := instances.ListInstanceOpts{Id: ddsInstance.Id}
    55  	newDdsInstance, err := instances.List(client, listOpts)
    56  	th.AssertNoErr(t, err)
    57  	if newDdsInstance.TotalCount == 0 {
    58  		t.Fatalf("No DDSv3 instance was found: %s", err)
    59  	}
    60  	t.Log(newDdsInstance.Instances[0])
    61  
    62  	t.Logf("Attempting to add 2 mongo nodes to cluster")
    63  	_, err = instances.AddNode(client, instances.AddNodeOpts{
    64  		InstanceId: newDdsInstance.Instances[0].Id,
    65  		Type:       "mongos",
    66  		SpecCode:   "dds.mongodb.s2.large.4.mongos",
    67  		Num:        2,
    68  	})
    69  	th.AssertNoErr(t, err)
    70  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
    71  	th.AssertNoErr(t, err)
    72  
    73  	t.Logf("Attempting to add 2 shard nodes to cluster")
    74  	_, err = instances.AddNode(client, instances.AddNodeOpts{
    75  		InstanceId: newDdsInstance.Instances[0].Id,
    76  		Type:       "shard",
    77  		SpecCode:   "dds.mongodb.s2.large.4.shard",
    78  		Num:        2,
    79  		Volume: &instances.VolumeNode{
    80  			Size: 70,
    81  		},
    82  	})
    83  	th.AssertNoErr(t, err)
    84  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
    85  	th.AssertNoErr(t, err)
    86  
    87  	t.Log("Enable config IP")
    88  	err = instances.EnableConfigIp(client, instances.EnableConfigIpOpts{
    89  		InstanceId: ddsInstance.Id,
    90  		Type:       "config",
    91  		Password:   "5ecurePa55w0rd@@",
    92  	})
    93  	th.AssertNoErr(t, err)
    94  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
    95  	th.AssertNoErr(t, err)
    96  }
    97  
    98  func TestDdsReplicaLifeCycle(t *testing.T) {
    99  	client, err := clients.NewDdsV3Client()
   100  	th.AssertNoErr(t, err)
   101  
   102  	ddsInstance := createDdsReplicaInstance(t, client)
   103  	defer deleteDdsInstance(t, client, ddsInstance.Id)
   104  
   105  	listOpts := instances.ListInstanceOpts{Id: ddsInstance.Id}
   106  	newDdsInstance, err := instances.List(client, listOpts)
   107  	th.AssertNoErr(t, err)
   108  	if newDdsInstance.TotalCount == 0 {
   109  		t.Fatalf("No DDSv3 instance was found: %s", err)
   110  	}
   111  	t.Log(newDdsInstance.Instances[0])
   112  
   113  	err = instances.ChangePassword(client, instances.ChangePasswordOpt{
   114  		InstanceId: ddsInstance.Id,
   115  		UserPwd:    "5ecurePa55w0rd@@",
   116  	})
   117  	th.AssertNoErr(t, err)
   118  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
   119  	th.AssertNoErr(t, err)
   120  }
   121  
   122  func updateDdsInstance(t *testing.T, client *golangsdk.ServiceClient, instance instances.InstanceResponse) {
   123  	t.Log("Update name")
   124  
   125  	err := instances.UpdateName(client,
   126  		instances.UpdateNameOpt{
   127  			InstanceId:      instance.Id,
   128  			NewInstanceName: tools.RandomString("dds-acc-2-", 8),
   129  		})
   130  	th.AssertNoErr(t, err)
   131  
   132  	netClient, err := clients.NewNetworkV1Client()
   133  	th.AssertNoErr(t, err)
   134  
   135  	elasticIP := networking.CreateEip(t, netClient, 100)
   136  	t.Cleanup(func() {
   137  		networking.DeleteEip(t, netClient, elasticIP.ID)
   138  	})
   139  
   140  	t.Log("AttachEip")
   141  
   142  	job, err := instances.BindEIP(client, instances.BindEIPOpts{
   143  		PublicIpId: elasticIP.ID,
   144  		PublicIp:   elasticIP.PublicAddress,
   145  		NodeId:     instance.Groups[0].Nodes[0].Id,
   146  	})
   147  	th.AssertNoErr(t, err)
   148  
   149  	err = waitForJobCompleted(client, 600, *job)
   150  	th.AssertNoErr(t, err)
   151  
   152  	t.Log("UnbindEip")
   153  
   154  	job, err = instances.UnBindEIP(client, instance.Groups[0].Nodes[0].Id)
   155  	th.AssertNoErr(t, err)
   156  
   157  	err = waitForJobCompleted(client, 600, *job)
   158  	th.AssertNoErr(t, err)
   159  
   160  	err = waitForInstanceAvailable(client, 600, instance.Id)
   161  	th.AssertNoErr(t, err)
   162  	t.Log("Enable the SSL")
   163  	job, err = instances.SwitchSSL(client, instances.SSLOpt{InstanceId: instance.Id,
   164  		SSL: "1"})
   165  	th.AssertNoErr(t, err)
   166  	err = waitForJobCompleted(client, 600, *job)
   167  	th.AssertNoErr(t, err)
   168  
   169  	t.Log("Modify instance internal IP")
   170  	job, err = instances.ModifyInternalIp(client, instances.ModifyInternalIpOpts{
   171  		InstanceId: instance.Id,
   172  		NewIp:      "192.168.1.42",
   173  		NodeId:     instance.Groups[0].Nodes[0].Id,
   174  	})
   175  	th.AssertNoErr(t, err)
   176  	err = waitForJobCompleted(client, 600, *job)
   177  	th.AssertNoErr(t, err)
   178  
   179  	t.Log("Modify instance port")
   180  	job, err = instances.ModifyPort(client, instances.ModifyPortOpt{
   181  		InstanceId: instance.Id,
   182  		Port:       8636,
   183  	})
   184  	th.AssertNoErr(t, err)
   185  	err = waitForJobCompleted(client, 600, *job)
   186  	th.AssertNoErr(t, err)
   187  
   188  	t.Log("Modify instance SG")
   189  	_, err = instances.ModifySG(client, instances.ModifySGOpt{
   190  		InstanceId:      instance.Id,
   191  		SecurityGroupId: openstack.DefaultSecurityGroup(t),
   192  	})
   193  	th.AssertNoErr(t, err)
   194  	err = waitForJobCompleted(client, 600, *job)
   195  	th.AssertNoErr(t, err)
   196  
   197  	t.Log("Modify instance specs")
   198  	job, err = instances.ModifySpec(client, instances.ModifySpecOpt{
   199  		InstanceId:     instance.Id,
   200  		TargetId:       instance.Id,
   201  		TargetSpecCode: "dds.mongodb.s2.large.4.single",
   202  	})
   203  	th.AssertNoErr(t, err)
   204  	err = waitForJobCompleted(client, 600, *job)
   205  	th.AssertNoErr(t, err)
   206  
   207  	_, err = instances.Restart(client, instances.RestartOpts{
   208  		InstanceId: instance.Id,
   209  		TargetId:   instance.Id,
   210  	})
   211  	th.AssertNoErr(t, err)
   212  	err = waitForInstanceAvailable(client, 600, instance.Id)
   213  	th.AssertNoErr(t, err)
   214  
   215  	t.Log("Modify instance volume size")
   216  	job, err = instances.ScaleStorage(client, instances.ScaleStorageOpt{
   217  		InstanceId: instance.Id,
   218  		Size:       "60",
   219  		GroupId:    instance.Groups[0].Id,
   220  	})
   221  	th.AssertNoErr(t, err)
   222  	err = waitForJobCompleted(client, 600, *job)
   223  	th.AssertNoErr(t, err)
   224  }
   225  
   226  func createDdsSingleInstance(t *testing.T, client *golangsdk.ServiceClient) *instances.Instance {
   227  	prefix := "dds-acc-"
   228  	ddsName := tools.RandomString(prefix, 8)
   229  	az := clients.EnvOS.GetEnv("AVAILABILITY_ZONE")
   230  	if az == "" {
   231  		az = "eu-de-01"
   232  	}
   233  	cloud, err := clients.EnvOS.Cloud()
   234  	th.AssertNoErr(t, err)
   235  
   236  	vpcID := clients.EnvOS.GetEnv("VPC_ID")
   237  	subnetID := clients.EnvOS.GetEnv("NETWORK_ID")
   238  	if vpcID == "" || subnetID == "" {
   239  		t.Skip("One of OS_VPC_ID or OS_NETWORK_ID env vars is missing but RDS test requires using existing network")
   240  	}
   241  
   242  	createOpts := instances.CreateOpts{
   243  		Name: ddsName,
   244  		DataStore: instances.DataStore{
   245  			Type:          "DDS-Community",
   246  			Version:       "4.0",
   247  			StorageEngine: "wiredTiger",
   248  		},
   249  		Region:           cloud.RegionName,
   250  		AvailabilityZone: az,
   251  		VpcId:            vpcID,
   252  		SubnetId:         subnetID,
   253  		SecurityGroupId:  openstack.DefaultSecurityGroup(t),
   254  		Password:         "5ecurePa55w0rd@",
   255  		Mode:             "Single",
   256  		Flavor: []instances.Flavor{
   257  			{
   258  				Type:     "single",
   259  				Num:      1,
   260  				Storage:  "ULTRAHIGH",
   261  				Size:     20,
   262  				SpecCode: "dds.mongodb.s2.medium.4.single",
   263  			},
   264  		},
   265  		BackupStrategy: instances.BackupStrategy{
   266  			StartTime: "08:15-09:15",
   267  		},
   268  	}
   269  	ddsInstance, err := instances.Create(client, createOpts)
   270  	th.AssertNoErr(t, err)
   271  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
   272  	th.AssertNoErr(t, err)
   273  	t.Logf("DDSv3 replica set instance successfully created")
   274  	return ddsInstance
   275  }
   276  
   277  func createDdsReplicaInstance(t *testing.T, client *golangsdk.ServiceClient) *instances.Instance {
   278  	t.Logf("Attempting to create DDSv3 replica set instance")
   279  	prefix := "dds-acc-"
   280  	ddsName := tools.RandomString(prefix, 8)
   281  	az := clients.EnvOS.GetEnv("AVAILABILITY_ZONE")
   282  	if az == "" {
   283  		az = "eu-de-01"
   284  	}
   285  	cloud, err := clients.EnvOS.Cloud()
   286  	th.AssertNoErr(t, err)
   287  
   288  	vpcID := clients.EnvOS.GetEnv("VPC_ID")
   289  	subnetID := clients.EnvOS.GetEnv("NETWORK_ID")
   290  	if vpcID == "" || subnetID == "" {
   291  		t.Skip("One of OS_VPC_ID or OS_NETWORK_ID env vars is missing but RDS test requires using existing network")
   292  	}
   293  
   294  	createOpts := instances.CreateOpts{
   295  		Name: ddsName,
   296  		DataStore: instances.DataStore{
   297  			Type:          "DDS-Community",
   298  			Version:       "3.4",
   299  			StorageEngine: "wiredTiger",
   300  		},
   301  		Region:           cloud.RegionName,
   302  		AvailabilityZone: az,
   303  		VpcId:            vpcID,
   304  		SubnetId:         subnetID,
   305  		SecurityGroupId:  openstack.DefaultSecurityGroup(t),
   306  		Password:         "5ecurePa55w0rd@",
   307  		Mode:             "ReplicaSet",
   308  		Flavor: []instances.Flavor{
   309  			{
   310  				Type:     "replica",
   311  				Num:      1,
   312  				Storage:  "ULTRAHIGH",
   313  				Size:     20,
   314  				SpecCode: "dds.mongodb.s2.medium.4.repset",
   315  			},
   316  		},
   317  		BackupStrategy: instances.BackupStrategy{
   318  			StartTime: "08:15-09:15",
   319  		},
   320  		Tags: []tags.ResourceTag{
   321  			{
   322  				Key:   "muh",
   323  				Value: "kuh",
   324  			},
   325  			{
   326  				Key:   "muh2",
   327  				Value: "kuh2",
   328  			},
   329  		},
   330  	}
   331  	ddsInstance, err := instances.Create(client, createOpts)
   332  	th.AssertNoErr(t, err)
   333  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
   334  	th.AssertNoErr(t, err)
   335  	t.Logf("DDSv3 replica set instance successfully created")
   336  	return ddsInstance
   337  }
   338  
   339  func createDdsClusterInstance(t *testing.T, client *golangsdk.ServiceClient) *instances.Instance {
   340  	prefix := "dds-acc-"
   341  	ddsName := tools.RandomString(prefix, 8)
   342  	az := clients.EnvOS.GetEnv("AVAILABILITY_ZONE")
   343  	if az == "" {
   344  		az = "eu-de-01"
   345  	}
   346  	cloud, err := clients.EnvOS.Cloud()
   347  	th.AssertNoErr(t, err)
   348  
   349  	vpcID := clients.EnvOS.GetEnv("VPC_ID")
   350  	subnetID := clients.EnvOS.GetEnv("NETWORK_ID")
   351  	if vpcID == "" || subnetID == "" {
   352  		t.Skip("One of OS_VPC_ID or OS_NETWORK_ID env vars is missing but RDS test requires using existing network")
   353  	}
   354  
   355  	createOpts := instances.CreateOpts{
   356  		Name: ddsName,
   357  		DataStore: instances.DataStore{
   358  			Type:          "DDS-Community",
   359  			Version:       "3.4",
   360  			StorageEngine: "wiredTiger",
   361  		},
   362  		Region:           cloud.RegionName,
   363  		AvailabilityZone: az,
   364  		VpcId:            vpcID,
   365  		SubnetId:         subnetID,
   366  		SecurityGroupId:  openstack.DefaultSecurityGroup(t),
   367  		Password:         "5ecurePa55w0rd@",
   368  		Mode:             "Sharding",
   369  		Flavor: []instances.Flavor{
   370  			{
   371  				Type:     "mongos",
   372  				Num:      2,
   373  				Storage:  "ULTRAHIGH",
   374  				SpecCode: "dds.mongodb.s2.medium.4.mongos",
   375  			},
   376  			{
   377  				Type:     "shard",
   378  				Num:      2,
   379  				Storage:  "ULTRAHIGH",
   380  				Size:     20,
   381  				SpecCode: "dds.mongodb.s2.medium.4.shard",
   382  			},
   383  			{
   384  				Type:     "config",
   385  				Num:      1,
   386  				Storage:  "ULTRAHIGH",
   387  				Size:     20,
   388  				SpecCode: "dds.mongodb.s2.large.2.config",
   389  			},
   390  		},
   391  		BackupStrategy: instances.BackupStrategy{
   392  			StartTime: "08:15-09:15",
   393  		},
   394  		Tags: []tags.ResourceTag{
   395  			{Key: "muh",
   396  				Value: "kuh"},
   397  			{Key: "muh2",
   398  				Value: "kuh2"},
   399  		},
   400  	}
   401  	ddsInstance, err := instances.Create(client, createOpts)
   402  	th.AssertNoErr(t, err)
   403  	err = waitForInstanceAvailable(client, 600, ddsInstance.Id)
   404  	th.AssertNoErr(t, err)
   405  	t.Logf("DDSv3 replica set instance successfully created: %s", ddsInstance.Id)
   406  	return ddsInstance
   407  }
   408  
   409  func deleteDdsInstance(t *testing.T, client *golangsdk.ServiceClient, instanceId string) {
   410  	t.Logf("Attempting to delete DDSv3 instance: %s", instanceId)
   411  
   412  	_, err := instances.Delete(client, instanceId)
   413  	if err != nil {
   414  		t.Fatalf("Unable to delete DDSv3 instance: %s", err)
   415  	}
   416  	err = waitForInstanceDelete(client, 600, instanceId)
   417  	if err != nil {
   418  		t.Fatalf("Error waiting delete DDSv3 instance: %s", err)
   419  	}
   420  	t.Logf("DDSv3 instance deleted successfully: %s", instanceId)
   421  }
   422  
   423  func waitForJobCompleted(client *golangsdk.ServiceClient, secs int, jobID string) error {
   424  	jobClient := *client
   425  	jobClient.ResourceBase = jobClient.Endpoint
   426  
   427  	return golangsdk.WaitFor(secs, func() (bool, error) {
   428  		job, err := ddsjob.Get(client, jobID)
   429  		if err != nil {
   430  			return false, err
   431  		}
   432  
   433  		if job.Status == "Completed" {
   434  			return true, nil
   435  		}
   436  		if job.Status == "Failed" {
   437  			err = fmt.Errorf("Job failed %s.\n", job.Status)
   438  			return false, err
   439  		}
   440  
   441  		time.Sleep(5 * time.Second)
   442  		return false, nil
   443  	})
   444  }
   445  
   446  func waitForInstanceAvailable(client *golangsdk.ServiceClient, secs int, instanceId string) error {
   447  	return golangsdk.WaitFor(secs, func() (bool, error) {
   448  		listOpts := instances.ListInstanceOpts{
   449  			Id: instanceId,
   450  		}
   451  		ddsInstances, err := instances.List(client, listOpts)
   452  		if err != nil {
   453  			return false, err
   454  		}
   455  		if ddsInstances.TotalCount == 1 {
   456  			dds := ddsInstances.Instances
   457  			if len(dds) == 1 && len(dds[0].Actions) == 0 && dds[0].Status == "normal" {
   458  				return true, nil
   459  			}
   460  			return false, nil
   461  		}
   462  		return false, nil
   463  	})
   464  }
   465  
   466  func waitForInstanceDelete(client *golangsdk.ServiceClient, secs int, instanceId string) error {
   467  	return golangsdk.WaitFor(secs, func() (bool, error) {
   468  		listOpts := instances.ListInstanceOpts{
   469  			Id: instanceId,
   470  		}
   471  		ddsInstances, err := instances.List(client, listOpts)
   472  		if err != nil {
   473  			return false, err
   474  		}
   475  		if err != nil {
   476  			if _, ok := err.(golangsdk.ErrDefault404); ok {
   477  				return true, nil
   478  			}
   479  			return false, err
   480  		}
   481  		if ddsInstances.TotalCount == 0 {
   482  			return true, nil
   483  		}
   484  		return false, nil
   485  	})
   486  }