Skip to content

Commit 348e671

Browse files
thekraussKrauss Vesset
authored andcommitted
feat(instance) public cloud instances with multiple interfaces
1 parent 6f1e76d commit 348e671

File tree

5 files changed

+242
-162
lines changed

5 files changed

+242
-162
lines changed

env.sh

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,2 @@
11
#!/usr/bin/env bash
22

3-
export OVH_ENDPOINT="ovh-eu"
4-
export OVH_APPLICATION_KEY="000693a9655db1b5"
5-
export OVH_APPLICATION_SECRET="dda3dcae9b4fbd41461c07d100da6586"
6-
export OVH_CONSUMER_KEY="055d118f9c3ca88b4fba9ae1b984fdf8"
7-
8-
export OVH_DOMAIN_TEST="syk-edu.com"
9-
10-
export TF_ACC=1
11-
12-
echo "[OK] OVH environment variables exported for acceptance tests."

examples/resources/cloud_project_instance/example_1.tf

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,61 @@ resource "ovh_cloud_project_instance" "instance" {
1616
public = true
1717
}
1818
}
19+
20+
21+
## with Multiple Network Interfaces
22+
23+
resource "ovh_cloud_project_network_private" "net_front" {
24+
service_name = "XXX"
25+
name = "public-front"
26+
regions = ["GRA11"]
27+
}
28+
29+
resource "ovh_cloud_project_subnet" "subnet_front" {
30+
service_name = "XXX"
31+
network_id = ovh_cloud_project_network_private.net_front.id
32+
region = "GRA11"
33+
network = "10.0.1.0/24"
34+
dhcp = true
35+
}
36+
37+
resource "ovh_cloud_project_network_private" "net_back" {
38+
service_name = "XXX"
39+
name = "private-back"
40+
regions = ["GRA11"]
41+
}
42+
43+
resource "ovh_cloud_project_subnet" "subnet_back" {
44+
service_name = "XXX"
45+
network_id = private.net_back.id
46+
region = "GRA11"
47+
network = "10.0.2.0/24"
48+
dhcp = true
49+
}
50+
51+
resource "ovh_cloud_project_instance" "multinic_instance" {
52+
service_name = "XXX"
53+
region = "GRA11"
54+
name = "multi-nic-instance"
55+
flavor_id = "UUID"
56+
image_id = "UUID"
57+
58+
network {
59+
public = true
60+
61+
private {
62+
network {
63+
id = private.net_front.id
64+
subnet_id = subnet.subnet_front.id
65+
}
66+
ip = "10.0.1.10"
67+
}
68+
69+
private {
70+
network {
71+
id = private.net_back.id
72+
subnet_id = subnet.subnet_back.id
73+
}
74+
}
75+
}
76+
}

ovh/resource_cloud_project_instance.go

Lines changed: 5 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ func resourceCloudProjectInstance() *schema.Resource {
187187
Type: schema.TypeList,
188188
Required: true,
189189
ForceNew: true,
190-
Description: "Network information(multiple NICs)",
190+
MaxItems: 1,
191+
Description: "Network information",
191192
Elem: &schema.Resource{
192193
Schema: map[string]*schema.Schema{
193194
"public": {
@@ -205,7 +206,6 @@ func resourceCloudProjectInstance() *schema.Resource {
205206
"floating_ip": {
206207
Type: schema.TypeSet,
207208
Optional: true,
208-
MaxItems: 1,
209209
Description: "Existing floating IP",
210210
ForceNew: true,
211211
Elem: &schema.Resource{
@@ -430,6 +430,7 @@ func resourceCloudProjectInstanceCreate(ctx context.Context, d *schema.ResourceD
430430
config := meta.(*Config)
431431
serviceName := d.Get("service_name").(string)
432432
region := d.Get("region").(string)
433+
433434
params := new(CloudProjectInstanceCreateOpts)
434435
params.FromResource(d)
435436

@@ -438,24 +439,9 @@ func resourceCloudProjectInstanceCreate(ctx context.Context, d *schema.ResourceD
438439
url.PathEscape(region),
439440
)
440441

441-
payload := map[string]interface{}{
442-
"auto_backup": params.AutoBackup,
443-
"availabilityZone": params.AvailabilityZone,
444-
"billingPeriod": params.BillingPeriod,
445-
"bootFrom": params.BootFrom,
446-
"bulk": params.Bulk,
447-
"flavor": params.Flavor,
448-
"group": params.Group,
449-
"name": params.Name,
450-
"sshKey": params.SshKey,
451-
"sshKeyCreate": params.SshKeyCreate,
452-
"userData": params.UserData,
453-
"network": networksToPayload(params.Networks), // multi NIC
454-
}
455-
456442
r := &CloudProjectOperationResponse{}
457-
if err := config.OVHClient.Post(endpoint, payload, r); err != nil {
458-
return diag.Errorf("calling %s with params %v:\n\t %q", endpoint, payload, err)
443+
if err := config.OVHClient.Post(endpoint, params, r); err != nil {
444+
return diag.Errorf("calling %s with params %v:\n\t %q", endpoint, params, err)
459445
}
460446

461447
instanceID, err := waitForCloudProjectOperation(ctx, config.OVHClient, serviceName, r.Id, "instance#create", d.Timeout(schema.TimeoutCreate))
@@ -542,76 +528,3 @@ func resourceCloudProjectInstanceDelete(ctx context.Context, d *schema.ResourceD
542528
log.Printf("[DEBUG] Deleted Public Cloud %s Instance %s", serviceName, id)
543529
return nil
544530
}
545-
546-
func networksToPayload(networks []*Network) []interface{} {
547-
payload := make([]interface{}, 0, len(networks))
548-
for _, net := range networks {
549-
netMap := map[string]interface{}{
550-
"public": net.Public,
551-
}
552-
553-
if len(net.Private) > 0 {
554-
privateList := make([]interface{}, 0, len(net.Private))
555-
for _, p := range net.Private {
556-
pMap := map[string]interface{}{}
557-
558-
if p.FloatingIP != nil {
559-
pMap["floating_ip"] = []map[string]interface{}{
560-
{"id": p.FloatingIP.ID},
561-
}
562-
}
563-
564-
if p.FloatingIPCreate != nil {
565-
pMap["floating_ip_create"] = []map[string]interface{}{
566-
{"description": p.FloatingIPCreate.Description},
567-
}
568-
}
569-
570-
if p.Gateway != nil {
571-
pMap["gateway"] = []map[string]interface{}{
572-
{"id": p.Gateway.ID},
573-
}
574-
}
575-
576-
if p.GatewayCreate != nil {
577-
pMap["gateway_create"] = []map[string]interface{}{
578-
{"model": p.GatewayCreate.Model, "name": p.GatewayCreate.Name},
579-
}
580-
}
581-
582-
if p.IP != "" {
583-
pMap["ip"] = p.IP
584-
}
585-
586-
if p.Network != nil {
587-
pMap["network"] = []map[string]interface{}{
588-
{"id": p.Network.ID, "subnet_id": p.Network.SubnetID},
589-
}
590-
}
591-
592-
if p.NetworkCreate != nil {
593-
subnetList := []map[string]interface{}{
594-
{
595-
"cidr": p.NetworkCreate.Subnet.CIDR,
596-
"enable_dhcp": p.NetworkCreate.Subnet.EnableDHCP,
597-
"ip_version": p.NetworkCreate.Subnet.IPVersion,
598-
},
599-
}
600-
pMap["network_create"] = []map[string]interface{}{
601-
{
602-
"name": p.NetworkCreate.Name,
603-
"vlan_id": p.NetworkCreate.VlanId,
604-
"subnet": subnetList,
605-
},
606-
}
607-
}
608-
609-
privateList = append(privateList, pMap)
610-
}
611-
netMap["private"] = privateList
612-
}
613-
614-
payload = append(payload, netMap)
615-
}
616-
return payload
617-
}

ovh/resource_cloud_project_instance_test.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,118 @@ func TestAccCloudProjectInstance_privateNetworkAlreadyExists(t *testing.T) {
380380
},
381381
})
382382
}
383+
384+
func TestAccCloudProjectInstance_multiNIC(t *testing.T) {
385+
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
386+
region := os.Getenv("OVH_CLOUD_PROJECT_REGION_TEST")
387+
flavor, image, err := getFlavorAndImage(serviceName, region)
388+
if err != nil {
389+
t.Skipf("failed to retrieve a flavor and an image: %s", err)
390+
}
391+
392+
rName := acctest.RandomWithPrefix(test_prefix)
393+
netName1 := fmt.Sprintf("%s_net1", rName)
394+
netName2 := fmt.Sprintf("%s_net2", rName)
395+
396+
vlanID1 := rand.Intn(2000) + 2
397+
vlanID2 := vlanID1 + 1
398+
399+
var testCreateInstanceMultiNIC = fmt.Sprintf(`
400+
resource "private" "net1" {
401+
service_name = "%s"
402+
name = "%s"
403+
regions = ["%s"]
404+
vlan_id = %d
405+
}
406+
407+
resource "ovh_cloud_project_subnet" "sub1" {
408+
service_name = "%s"
409+
network_id = private.net1.id
410+
region = "%s"
411+
network = "192.168.1.0/24"
412+
dhcp = true
413+
start = "192.168.1.100"
414+
end = "192.168.1.200"
415+
no_gateway = false
416+
}
417+
418+
resource "private" "net2" {
419+
service_name = "%s"
420+
name = "%s"
421+
regions = ["%s"]
422+
vlan_id = %d
423+
}
424+
425+
resource "ovh_cloud_project_subnet" "sub2" {
426+
service_name = "%s"
427+
network_id = private.net2.id
428+
region = "%s"
429+
network = "192.168.2.0/24"
430+
dhcp = true
431+
start = "192.168.2.100"
432+
end = "192.168.2.200"
433+
no_gateway = false
434+
}
435+
436+
resource "ovh_cloud_project_instance" "multi_nic" {
437+
service_name = "%s"
438+
region = "%s"
439+
name = "%s"
440+
billing_period = "hourly"
441+
442+
flavor {
443+
flavor_id = "%s"
444+
}
445+
boot_from {
446+
image_id = "%s"
447+
}
448+
449+
network {
450+
# Interface Publique
451+
public = true
452+
453+
# Interface Privée 1
454+
private {
455+
network {
456+
id = private.net1.id
457+
subnet_id = ovh_cloud_project_subnet.sub1.id
458+
}
459+
}
460+
461+
# Interface Privée 2
462+
private {
463+
network {
464+
id = private.net2.id
465+
subnet_id = ovh_cloud_project_subnet.sub2.id
466+
}
467+
}
468+
}
469+
}
470+
`,
471+
serviceName, netName1, region, vlanID1,
472+
serviceName, region,
473+
serviceName, netName2, region, vlanID2,
474+
serviceName, region,
475+
serviceName, region, rName, flavor, image,
476+
)
477+
478+
resource.Test(t, resource.TestCase{
479+
PreCheck: func() {
480+
testAccPreCheckCloud(t)
481+
testAccCheckCloudProjectExists(t)
482+
},
483+
Providers: testAccProviders,
484+
Steps: []resource.TestStep{
485+
{
486+
Config: testCreateInstanceMultiNIC,
487+
Check: resource.ComposeTestCheckFunc(
488+
resource.TestCheckResourceAttrSet("ovh_cloud_project_instance.multi_nic", "id"),
489+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.multi_nic", "network.0.private.#", "2"),
490+
resource.TestCheckResourceAttrSet("ovh_cloud_project_instance.multi_nic", "addresses.0.ip"),
491+
resource.TestCheckResourceAttrSet("ovh_cloud_project_instance.multi_nic", "addresses.1.ip"),
492+
resource.TestCheckResourceAttrSet("ovh_cloud_project_instance.multi_nic", "addresses.2.ip"),
493+
),
494+
},
495+
},
496+
})
497+
}

0 commit comments

Comments
 (0)