Skip to content

Commit

Permalink
datasource & resource instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Thibaut Di Prima authored and Arthur Amstutz committed Jan 24, 2025
1 parent 7179dfc commit 657a2f0
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 172 deletions.
1 change: 1 addition & 0 deletions .cds/terraform-provider-ovh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ workflow:
one_at_a_time: true
parameters:
testargs: -run CloudProjectInstance
skipthispipeline: "{{.workflow.terraform-provider-ovh.pip.skipthistest.cloudproject}}"
pipeline: terraform-provider-ovh-testacc
when:
- success
Expand Down
29 changes: 12 additions & 17 deletions ovh/data_cloud_project_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func dataSourceCloudProjectInstance() *schema.Resource {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
Description: "Service name of the resource representing the id of the cloud project.",
Description: "Service name of the resource representing the id of the cloud project",
},
"region": {
Type: schema.TypeString,
Expand Down Expand Up @@ -57,7 +57,7 @@ func dataSourceCloudProjectInstance() *schema.Resource {
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Description: "Volume Id",
Description: "Volume id",
Computed: true,
},
},
Expand All @@ -75,12 +75,7 @@ func dataSourceCloudProjectInstance() *schema.Resource {
},
"name": {
Type: schema.TypeString,
Description: "Flavor name",
Computed: true,
},
"id": {
Type: schema.TypeString,
Description: "Instance id",
Description: "Instance name",
Computed: true,
},
"image_id": {
Expand All @@ -90,7 +85,7 @@ func dataSourceCloudProjectInstance() *schema.Resource {
},
"ssh_key": {
Type: schema.TypeString,
Description: "Instance task state",
Description: "SSH Key pair name",
Computed: true,
},
"task_state": {
Expand Down Expand Up @@ -119,20 +114,19 @@ func dataSourceCloudProjectInstanceRead(d *schema.ResourceData, meta interface{}
if err := config.OVHClient.Get(endpoint, &res); err != nil {
return helpers.CheckDeleted(d, err, endpoint)
}
log.Printf("[DEBUG] Read instance: %+v", res)

addresses := make([]map[string]interface{}, 0)
for i := range res.Addresses {
addresses := make([]map[string]interface{}, 0, len(res.Addresses))
for _, addr := range res.Addresses {
address := make(map[string]interface{})
address["ip"] = res.Addresses[i].Ip
address["version"] = res.Addresses[i].Version
address["ip"] = addr.Ip
address["version"] = addr.Version
addresses = append(addresses, address)
}

attachedVolumes := make([]map[string]interface{}, 0)
for i := range res.AttachedVolumes {
attachedVolumes := make([]map[string]interface{}, 0, len(res.AttachedVolumes))
for _, volume := range res.AttachedVolumes {
attachedVolume := make(map[string]interface{})
attachedVolume["id"] = res.AttachedVolumes[i].Id
attachedVolume["id"] = volume.Id
attachedVolumes = append(attachedVolumes, attachedVolume)
}

Expand All @@ -145,6 +139,7 @@ func dataSourceCloudProjectInstanceRead(d *schema.ResourceData, meta interface{}
d.Set("name", res.Name)
d.Set("ssh_key", res.SshKey)
d.Set("task_state", res.TaskState)
d.Set("attached_volumes", attachedVolumes)

return nil
}
18 changes: 9 additions & 9 deletions ovh/data_cloud_project_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func dataSourceCloudProjectInstances() *schema.Resource {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
Description: "Service name of the resource representing the id of the cloud project.",
Description: "Service name of the resource representing the id of the cloud project",
},
"region": {
Type: schema.TypeString,
Expand Down Expand Up @@ -55,12 +55,12 @@ func dataSourceCloudProjectInstances() *schema.Resource {
"attached_volumes": {
Type: schema.TypeList,
Computed: true,
Description: " Volumes attached to the instance",
Description: "Volumes attached to the instance",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Description: "Volume Id",
Description: "Volume id",
Computed: true,
},
},
Expand All @@ -78,7 +78,7 @@ func dataSourceCloudProjectInstances() *schema.Resource {
},
"name": {
Type: schema.TypeString,
Description: "Flavor name",
Description: "Instance name",
Computed: true,
},
"id": {
Expand All @@ -93,7 +93,7 @@ func dataSourceCloudProjectInstances() *schema.Resource {
},
"ssh_key": {
Type: schema.TypeString,
Description: "Instance task state",
Description: "SSH Key pair name",
Computed: true,
},
"task_state": {
Expand Down Expand Up @@ -124,10 +124,10 @@ func dataSourceCloudProjectInstancesRead(d *schema.ResourceData, meta interface{
return helpers.CheckDeleted(d, err, endpoint)
}

instances := make([]map[string]interface{}, len(res))
ids := make([]string, len(res))
for i, instance := range res {
instances[i] = instance.ToMap()
instances := make([]map[string]interface{}, 0, len(res))
ids := make([]string, 0, len(res))
for _, instance := range res {
instances = append(instances, instance.ToMap())
ids = append(ids, instance.Id)
}
sort.Strings(ids)
Expand Down
97 changes: 26 additions & 71 deletions ovh/resource_cloud_project_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import (
"fmt"
"log"
"net/url"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/ovh/go-ovh/ovh"
"github.com/ovh/terraform-provider-ovh/ovh/helpers"
)

Expand All @@ -25,7 +22,7 @@ func resourceCloudProjectInstance() *schema.Resource {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("OVH_CLOUD_PROJECT_SERVICE", nil),
Description: "Service name of the resource representing the id of the cloud project.",
Description: "Service name of the resource representing the id of the cloud project",
ForceNew: true,
},
"region": {
Expand Down Expand Up @@ -134,12 +131,12 @@ func resourceCloudProjectInstance() *schema.Resource {
Optional: true,
ForceNew: true,
MaxItems: 1,
Description: "Existing SSH Keypair",
Description: "Existing SSH Key pair",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "SSH Keypair name",
Description: "SSH Key pair name",
Required: true,
},
},
Expand All @@ -150,17 +147,17 @@ func resourceCloudProjectInstance() *schema.Resource {
Optional: true,
ForceNew: true,
MaxItems: 1,
Description: "Creatting SSH Keypair",
Description: "Add existing SSH Key pair into your Public Cloud project and link it to the instance",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "SSH Keypair name",
Description: "SSH Key pair name",
Required: true,
},
"public_key": {
Type: schema.TypeString,
Description: "Group id",
Description: "SSH Public Key",
Required: true,
},
},
Expand Down Expand Up @@ -211,12 +208,12 @@ func resourceCloudProjectInstance() *schema.Resource {
"attached_volumes": {
Type: schema.TypeSet,
Computed: true,
Description: " Volumes attached to the instance",
Description: "Volumes attached to the instance",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Description: "Volume Id",
Description: "Volume id",
Computed: true,
},
},
Expand Down Expand Up @@ -258,107 +255,65 @@ func resourceCloudProjectInstanceCreate(ctx context.Context, d *schema.ResourceD
params := new(CloudProjectInstanceCreateOpts)
params.FromResource(d)

r := &CloudProjectOperation{}

endpoint := fmt.Sprintf("/cloud/project/%s/region/%s/instance",
url.PathEscape(serviceName),
url.PathEscape(region),
)

r := &CloudProjectOperationResponse{}
if err := config.OVHClient.Post(endpoint, params, r); err != nil {
return diag.Errorf("calling %s with params %v:\n\t %q", endpoint, params, err)
}

err := waitForInstanceCreation(ctx, config.OVHClient, serviceName, r.Id)
instanceID, err := waitForCloudProjectOperation(ctx, config.OVHClient, serviceName, r.Id)
if err != nil {
return diag.Errorf("timeout instance creation: %s", err)
}

endpointInstance := fmt.Sprintf("/cloud/project/%s/operation/%s",
url.PathEscape(serviceName),
url.PathEscape(r.Id),
)

err = config.OVHClient.GetWithContext(ctx, endpointInstance, r)
if err != nil {
return diag.Errorf("failed to get instance id: %s", err)
}

d.SetId(r.SubOperations[0].ResourceId)
d.SetId(instanceID)
d.Set("region", region)

return resourceCloudProjectInstanceRead(ctx, d, meta)
}

func waitForInstanceCreation(ctx context.Context, client *ovh.Client, serviceName, operationId string) error {
stateConf := &retry.StateChangeConf{
Pending: []string{"null", "in-progress", "created", ""},
Target: []string{"completed"},
Refresh: func() (interface{}, string, error) {
res := &CloudProjectOperation{}
endpoint := fmt.Sprintf("/cloud/project/%s/operation/%s",
url.PathEscape(serviceName),
url.PathEscape(operationId),
)
err := client.GetWithContext(ctx, endpoint, res)
if err != nil {
return res, "", err
}
return res, res.Status, nil
},
Timeout: 360 * time.Second,
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err := stateConf.WaitForStateContext(ctx)
return err
}

func resourceCloudProjectInstanceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
config := meta.(*Config)
id := d.Id()
region := d.Get("region").(string)
serviceName := d.Get("service_name").(string)

r := &CloudProjectInstanceResponse{}

endpoint := fmt.Sprintf("/cloud/project/%s/region/%s/instance/%s",
url.PathEscape(serviceName),
url.PathEscape(region),
url.PathEscape(id),
)

r := &CloudProjectInstanceResponse{}
if err := config.OVHClient.Get(endpoint, r); err != nil {
return diag.Errorf("Error calling post %s:\n\t %q", endpoint, err)
return diag.Errorf("Error calling Get %s:\n\t %q", endpoint, err)
}

d.Set("flavor_id", r.FlavorId)
d.Set("flavor_name", r.FlavorName)
d.Set("image_id", r.ImageId)
d.Set("region", r.Region)
d.Set("task_state", r.TaskState)
d.Set("name", d.Get("name").(string))
d.Set("id", r.Id)

addresses := make([]map[string]interface{}, 0)
if r.Addresses != nil {
for _, add := range r.Addresses {
address := make(map[string]interface{})
address["ip"] = add.Ip
address["version"] = add.Version
addresses = append(addresses, address)
}
addresses := make([]map[string]interface{}, 0, len(r.Addresses))
for _, add := range r.Addresses {
address := make(map[string]interface{})
address["ip"] = add.Ip
address["version"] = add.Version
addresses = append(addresses, address)
}
d.Set("addresses", addresses)

attachedVolumes := make([]map[string]interface{}, 0)
if r.AttachedVolumes != nil {
for _, att := range r.AttachedVolumes {
attachedVolume := make(map[string]interface{})
attachedVolume["id"] = att.Id
attachedVolumes = append(attachedVolumes, attachedVolume)
}
attachedVolumes := make([]map[string]interface{}, 0, len(r.AttachedVolumes))
for _, att := range r.AttachedVolumes {
attachedVolume := make(map[string]interface{})
attachedVolume["id"] = att.Id
attachedVolumes = append(attachedVolumes, attachedVolume)
}
d.Set("attached_volumes", attachedVolumes)

Expand All @@ -380,11 +335,11 @@ func resourceCloudProjectInstanceDelete(ctx context.Context, d *schema.ResourceD
)

if err := config.OVHClient.Delete(endpoint, nil); err != nil {
return diag.Errorf("Error calling post %s:\n\t %q", endpoint, err)
return diag.Errorf("Error calling Delete %s:\n\t %q", endpoint, err)
}

d.SetId("")

log.Printf("[DEBUG] Deleted Public Cloud %s Gateway %s", serviceName, id)
log.Printf("[DEBUG] Deleted Public Cloud %s Instance %s", serviceName, id)
return nil
}
Loading

0 comments on commit 657a2f0

Please sign in to comment.