Skip to content

Commit b693c46

Browse files
authored
Merge pull request #861 from ovh/dev/aamstutz/fix-instance
fix: Correctly handle SSH keys in ovh_cloud_project_instance resource
2 parents 76970d5 + dcb80c4 commit b693c46

6 files changed

+80
-6
lines changed

ovh/resource_cloud_project_instance.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ func resourceCloudProjectInstance() *schema.Resource {
141141
},
142142
},
143143
},
144+
ExactlyOneOf: []string{"ssh_key", "ssh_key_create"},
144145
},
145146
"ssh_key_create": {
146147
Type: schema.TypeSet,
@@ -265,13 +266,12 @@ func resourceCloudProjectInstanceCreate(ctx context.Context, d *schema.ResourceD
265266
return diag.Errorf("calling %s with params %v:\n\t %q", endpoint, params, err)
266267
}
267268

268-
instanceID, err := waitForCloudProjectOperation(ctx, config.OVHClient, serviceName, r.Id)
269+
instanceID, err := waitForCloudProjectOperation(ctx, config.OVHClient, serviceName, r.Id, "instance#create")
269270
if err != nil {
270271
return diag.Errorf("timeout instance creation: %s", err)
271272
}
272273

273274
d.SetId(instanceID)
274-
d.Set("region", region)
275275

276276
return resourceCloudProjectInstanceRead(ctx, d, meta)
277277
}

ovh/resource_cloud_project_instance_test.go

+60
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"testing"
88

9+
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
910
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1011
)
1112

@@ -104,3 +105,62 @@ func TestAccCloudProjectInstance_basic(t *testing.T) {
104105
},
105106
})
106107
}
108+
109+
func TestAccCloudProjectInstance_withSSHKeyCreate(t *testing.T) {
110+
serviceName := os.Getenv("OVH_CLOUD_PROJECT_SERVICE_TEST")
111+
region := os.Getenv("OVH_CLOUD_PROJECT_REGION_TEST")
112+
flavor, image, err := getFlavorAndImage(serviceName, region)
113+
if err != nil {
114+
t.Fatalf("failed to retrieve a flavor and an image: %s", err)
115+
}
116+
117+
sshKeyName := acctest.RandomWithPrefix(test_prefix)
118+
119+
var testCreateInstance = fmt.Sprintf(`
120+
resource "ovh_cloud_project_instance" "instance" {
121+
service_name = "%s"
122+
region = "%s"
123+
billing_period = "hourly"
124+
boot_from {
125+
image_id = "%s"
126+
}
127+
flavor {
128+
flavor_id = "%s"
129+
}
130+
name = "TestInstance"
131+
ssh_key_create {
132+
name = "%s"
133+
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9xPpdqP3sx2H+gcBm65tJEaUbuifQ1uGkgrWtNY0PRKNNPdy+3yoVOtxk6Vjo4YZ0EU/JhmQfnrK7X7Q5vhqYxmozi0LiTRt0BxgqHJ+4hWTWMIOgr+C2jLx7ZsCReRk+fy5AHr6h0PHQEuXVLXeUy/TDyuY2JPtUZ5jcqvLYgQ== my-key"
134+
}
135+
network {
136+
public = true
137+
}
138+
}
139+
`,
140+
serviceName,
141+
region,
142+
image,
143+
flavor,
144+
sshKeyName)
145+
146+
resource.Test(t, resource.TestCase{
147+
PreCheck: func() {
148+
testAccPreCheckCloud(t)
149+
testAccCheckCloudProjectExists(t)
150+
},
151+
Providers: testAccProviders,
152+
Steps: []resource.TestStep{
153+
{
154+
Config: testCreateInstance,
155+
Check: resource.ComposeTestCheckFunc(
156+
resource.TestCheckResourceAttrSet("ovh_cloud_project_instance.instance", "id"),
157+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.instance", "flavor_name", "b2-7"),
158+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.instance", "flavor_id", flavor),
159+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.instance", "image_id", image),
160+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.instance", "region", region),
161+
resource.TestCheckResourceAttr("ovh_cloud_project_instance.instance", "name", "TestInstance"),
162+
),
163+
},
164+
},
165+
})
166+
}

ovh/resource_cloud_project_loadbalancer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (r *cloudProjectLoadbalancerResource) Create(ctx context.Context, req resou
9797
}
9898

9999
// Wait for operation to be completed
100-
resourceID, err := waitForCloudProjectOperation(ctx, r.config.OVHClient, data.ServiceName.ValueString(), operation.Id)
100+
resourceID, err := waitForCloudProjectOperation(ctx, r.config.OVHClient, data.ServiceName.ValueString(), operation.Id, "")
101101
if err != nil {
102102
resp.Diagnostics.AddError("error waiting for operation", err.Error())
103103
}

ovh/resource_cloud_project_region_network.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func (r *cloudProjectRegionNetworkResource) Create(ctx context.Context, req reso
8383
}
8484

8585
// Wait for operation to complete
86-
networkID, err := waitForCloudProjectOperation(ctx, r.config.OVHClient, data.ServiceName.ValueString(), operation.Id)
86+
networkID, err := waitForCloudProjectOperation(ctx, r.config.OVHClient, data.ServiceName.ValueString(), operation.Id, "")
8787
if err != nil {
8888
resp.Diagnostics.AddError(fmt.Sprintf("error waiting for operation %s", operation.Id), err.Error())
8989
return

ovh/types_cloud.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ type CloudProjectOperationResponse struct {
6969

7070
type CloudProjectSubOperation struct {
7171
ResourceId *string `json:"resourceId"`
72+
Action string `json:"action"`
7273
}
7374

74-
func waitForCloudProjectOperation(ctx context.Context, c *ovh.Client, serviceName, operationId string) (string, error) {
75+
func waitForCloudProjectOperation(ctx context.Context, c *ovh.Client, serviceName, operationId, actionType string) (string, error) {
7576
endpoint := fmt.Sprintf("/cloud/project/%s/operation/%s", url.PathEscape(serviceName), url.PathEscape(operationId))
7677
resourceID := ""
7778
err := retry.RetryContext(ctx, 10*time.Minute, func() *retry.RetryError {
@@ -86,6 +87,13 @@ func waitForCloudProjectOperation(ctx context.Context, c *ovh.Client, serviceNam
8687
case "completed":
8788
if ro.ResourceId != nil {
8889
resourceID = *ro.ResourceId
90+
} else if len(ro.SubOperations) > 0 && actionType != "" {
91+
for _, subOp := range ro.SubOperations {
92+
if subOp.Action == actionType && subOp.ResourceId != nil {
93+
resourceID = *subOp.ResourceId
94+
break
95+
}
96+
}
8997
} else if len(ro.SubOperations) > 0 && ro.SubOperations[0].ResourceId != nil {
9098
resourceID = *ro.SubOperations[0].ResourceId
9199
}

ovh/types_cloud_project_instance.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ func GetGroup(i interface{}) *Group {
175175
groupOut := Group{}
176176

177177
groupSet := i.(*schema.Set).List()
178+
if len(groupSet) == 0 {
179+
return nil
180+
}
178181
for _, group := range groupSet {
179182
mapping := group.(map[string]interface{})
180183
groupOut.GroupId = mapping["id"].(string)
@@ -189,6 +192,9 @@ func GetSshKey(i interface{}) *SshKey {
189192
sshOutput := SshKey{}
190193

191194
sshSet := i.(*schema.Set).List()
195+
if len(sshSet) == 0 {
196+
return nil
197+
}
192198
for _, ssh := range sshSet {
193199
mapping := ssh.(map[string]interface{})
194200
sshOutput.Name = mapping["name"].(string)
@@ -210,7 +216,7 @@ func GetSshKeyCreate(i interface{}) *SshKeyCreate {
210216
for _, ssh := range sshCreateSet {
211217
mapping := ssh.(map[string]interface{})
212218
sshCreateOutput.Name = mapping["name"].(string)
213-
sshCreateOutput.Name = mapping["public_key"].(string)
219+
sshCreateOutput.PublicKey = mapping["public_key"].(string)
214220
}
215221

216222
return &sshCreateOutput

0 commit comments

Comments
 (0)