Skip to content

Commit

Permalink
feat(instance): data source image (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
kindermoumoute authored Dec 5, 2019
1 parent 8abd795 commit f69dec3
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 3 deletions.
166 changes: 166 additions & 0 deletions scaleway/data_source_instance_image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package scaleway

import (
"fmt"
"sort"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func dataSourceScalewayInstanceImage() *schema.Resource {
return &schema.Resource{
Read: dataSourceScalewayInstanceImageRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Description: "Exact name of the desired image",
ConflictsWith: []string{"image_id"},
},
"image_id": {
Type: schema.TypeString,
Optional: true,
Description: "ID of the desired image",
ConflictsWith: []string{"name", "architecture"},
},
"architecture": {
Type: schema.TypeString,
Optional: true,
Default: instance.ArchX86_64.String(),
Description: "Architecture of the desired image",
ConflictsWith: []string{"image_id"},
},
"latest": {
Type: schema.TypeBool,
Optional: true,
Default: true,
Description: "Select most recent image if multiple match",
ConflictsWith: []string{"image_id"},
},
"zone": zoneSchema(),
"organization_id": organizationIDSchema(),

"public": {
Type: schema.TypeBool,
Computed: true,
Description: "Indication if the image is public",
},
"default_bootscript_id": {
Type: schema.TypeString,
Computed: true,
Description: "ID of the bootscript associated with this image",
},
"root_volume_id": {
Type: schema.TypeString,
Computed: true,
Description: "ID of the root volume associated with this image",
},
"additional_volume_ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "The additional volume IDs attached to the image",
},
"from_server_id": {
Type: schema.TypeString,
Computed: true,
Description: "ID of the server the image is originated from",
},
"creation_date": {
Type: schema.TypeString,
Computed: true,
Description: "Date when the image was created",
},
"modification_date": {
Type: schema.TypeString,
Computed: true,
Description: "Date when the image was updated",
},
"state": {
Type: schema.TypeString,
Computed: true,
Description: "State of the image",
},
},
}
}

func dataSourceScalewayInstanceImageRead(d *schema.ResourceData, m interface{}) error {
meta := m.(*Meta)
instanceApi, zone, err := getInstanceAPIWithZone(d, meta)
if err != nil {
return err
}

imageID, ok := d.GetOk("image_id")
if !ok { // Get instance by name, zone, and arch.
res, err := instanceApi.ListImages(&instance.ListImagesRequest{
Zone: zone,
Name: expandStringPtr(d.Get("name")),
Arch: expandStringPtr(d.Get("architecture")),
}, scw.WithAllPages())
if err != nil {
return err
}
if len(res.Images) == 0 {
return fmt.Errorf("no image found with the name %s and architecture %s in zone %s", d.Get("name"), d.Get("architecture"), zone)
}
if len(res.Images) > 1 && !d.Get("latest").(bool) {
return fmt.Errorf("%d images found with the same name %s and architecture %s in zone %s", len(res.Images), d.Get("name"), d.Get("architecture"), zone)
}
sort.Slice(res.Images, func(i, j int) bool {
return res.Images[i].ModificationDate.After(res.Images[j].ModificationDate)
})
imageID = res.Images[0].ID
}

zonedID := datasourceNewZonedID(imageID, zone)
zone, imageID, _ = parseZonedID(zonedID)

d.SetId(zonedID)
d.Set("image_id", zonedID)
d.Set("zone", zone)

resp, err := instanceApi.GetImage(&instance.GetImageRequest{
Zone: zone,
ImageID: imageID.(string),
})
if err != nil {
return err
}

d.Set("organization_id", resp.Image.Organization)
d.Set("architecture", resp.Image.Arch)
d.Set("name", resp.Image.Name)

d.Set("creation_date", flattenTime(&resp.Image.CreationDate))
d.Set("modification_date", flattenTime(&resp.Image.ModificationDate))
d.Set("public", resp.Image.Public)
d.Set("from_server_id", resp.Image.FromServer)
d.Set("state", resp.Image.State.String())

if resp.Image.DefaultBootscript != nil {
d.Set("default_bootscript_id", resp.Image.DefaultBootscript.ID)
} else {
d.Set("default_bootscript_id", "")
}

if resp.Image.RootVolume != nil {
d.Set("root_volume_id", resp.Image.RootVolume.ID)
} else {
d.Set("root_volume_id", "")
}

additionalVolumeIDs := []string(nil)
for _, volume := range orderVolumes(resp.Image.ExtraVolumes) {
additionalVolumeIDs = append(additionalVolumeIDs, volume.ID)
}
d.Set("additional_volume_ids", additionalVolumeIDs)

return nil
}
80 changes: 80 additions & 0 deletions scaleway/data_source_instance_image_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package scaleway

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
)

func TestAccScalewayDataSourceInstanceImage_Basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: `
data "scaleway_instance_image" "test1" {
name = "golang 1.10"
}
data "scaleway_instance_image" "test2" {
image_id = "43213956-c7a3-44b8-9d96-d51fa7457969"
}
data "scaleway_instance_image" "test3" {
image_id = "fr-par-1/43213956-c7a3-44b8-9d96-d51fa7457969"
}`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayInstanceImageExists("data.scaleway_instance_image.test1"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test1", "name", "Golang 1.10"),
testAccCheckScalewayInstanceImageExists("data.scaleway_instance_image.test2"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "image_id", "fr-par-1/43213956-c7a3-44b8-9d96-d51fa7457969"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "name", "Golang 1.10"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "architecture", "x86_64"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "creation_date", "2018-04-12T10:22:46Z"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "modification_date", "2018-04-12T15:02:26Z"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "latest", "true"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "public", "true"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "from_server_id", ""),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "state", "available"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "default_bootscript_id", "b1e68c26-a19c-4eac-9222-498b22bd7ad9"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test2", "root_volume_id", "8fa97c03-ca3b-4267-ba19-2d38190b1c82"),
resource.TestCheckNoResourceAttr("data.scaleway_instance_image.test2", "additional_volume_ids"),
testAccCheckScalewayInstanceImageExists("data.scaleway_instance_image.test3"),
resource.TestCheckResourceAttr("data.scaleway_instance_image.test3", "name", "Golang 1.10"),
),
},
},
})
}

func testAccCheckScalewayInstanceImageExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]

if !ok {
return fmt.Errorf("not found: %s", n)
}

zone, ID, err := parseZonedID(rs.Primary.ID)
if err != nil {
return err
}

meta := testAccProvider.Meta().(*Meta)
instanceApi := instance.NewAPI(meta.scwClient)
_, err = instanceApi.GetImage(&instance.GetImageRequest{
ImageID: ID,
Zone: zone,
})

if err != nil {
return err
}

return nil
}
}
3 changes: 2 additions & 1 deletion scaleway/data_source_instance_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func dataSourceScalewayInstanceSecurityGroup() *schema.Resource {
Expand Down Expand Up @@ -42,7 +43,7 @@ func dataSourceScalewayInstanceSecurityGroupRead(d *schema.ResourceData, m inter
res, err := instanceApi.ListSecurityGroups(&instance.ListSecurityGroupsRequest{
Zone: zone,
Name: String(d.Get("name").(string)),
})
}, scw.WithAllPages())
if err != nil {
return err
}
Expand Down
7 changes: 7 additions & 0 deletions scaleway/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,13 @@ func testAccGetResourceAttr(resourceName string, attrName string, dest *string)
}
}

func flattenTime(date *time.Time) interface{} {
if date != nil {
return date.Format(time.RFC3339)
}
return ""
}

func flattenDuration(duration *time.Duration) interface{} {
if duration != nil {
return duration.String()
Expand Down
1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ func Provider() terraform.ResourceProvider {
"scaleway_account_ssh_key": dataSourceScalewayAccountSSHKey(),
"scaleway_instance_security_group": dataSourceScalewayInstanceSecurityGroup(),
"scaleway_instance_server": dataSourceScalewayInstanceServer(),
"scaleway_instance_image": dataSourceScalewayInstanceImage(),
},
}

Expand Down
3 changes: 3 additions & 0 deletions website/docs/d/image.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ description: |-

# scaleway_image

**DEPRECATED**: This resource is deprecated and will be removed in `v2.0+`.
Please use `scaleway_instance_image` instead.

Use this data source to get the ID of a registered Image for use with the
`scaleway_server` resource.

Expand Down
60 changes: 60 additions & 0 deletions website/docs/d/instance_image.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
layout: "scaleway"
page_title: "Scaleway: scaleway_instance_image"
description: |-
Gets information about an Instance Image.
---

# scaleway_instance_image

Gets information about an instance image.

## Example Usage

```hcl
// Get info by image name
data "scaleway_instance_image" "my_image" {
name = "ubuntu bionic"
}
// Get info by image id
data "scaleway_instance_image" "my_image" {
image_id = "11111111-1111-1111-1111-111111111111"
}
```

## Argument Reference

- `name` - (Optional) The image name. Only one of `name` and `image_id` should be specified.

- `image_id` - (Optional) The image id. Only one of `name` and `image_id` should be specified.

- `architecture` - (Optional, default `x86_64`) The architecture the image is compatible with. Possible values are: `x86_64` or `arm`.

- `latest` - (Optional, default `true`) Use the latest image ID.

- `zone` - (Defaults to [provider](../index.html#zone) `zone`) The [zone](../guides/regions_and_zones.html#zones) in which the image should be created.

## Attributes Reference

In addition to all above arguments, the following attributes are exported:

- `id` - The ID of the image.

- `organization_id` - The ID of the organization the image is associated with.

- `creation_date` - Date of the image creation.

- `modification_date` - Date of image latest update.

- `public` - Set to `true` if the image is public.

- `from_server_id` - ID of the server the image if based from.

- `state` - State of the image. Possible values are: `available`, `creating` or `error`.

- `default_bootscript_id` - ID of the default bootscript for this image.

- `root_volume_id` - ID of the root volume in this image.

- `additional_volume_ids` - IDs of the additional volumes in this image.
3 changes: 3 additions & 0 deletions website/docs/d/security_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ description: |-

# scaleway_security_group

**DEPRECATED**: This resource is deprecated and will be removed in `v2.0+`.
Please use `scaleway_instance_security_group` instead.

Gets information about a Security Group.

## Example Usage
Expand Down
7 changes: 5 additions & 2 deletions website/scaleway.erb
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@
<a href="/docs/providers/scaleway/d/instance_server.html">scaleway_instance_server</a>
</li>
<li>
<a href="/docs/providers/scaleway/d/bootscript.html">scaleway_bootscript</a>
<a href="/docs/providers/scaleway/d/instance_image.html">scaleway_instance_image</a>
</li>
<li>
<a href="/docs/providers/scaleway/d/image.html">scaleway_image</a>
<a href="/docs/providers/scaleway/d/bootscript.html">scaleway_bootscript</a>
</li>
<li>
<a href="/docs/providers/scaleway/d/instance_security_group.html">scaleway_instance_security_group</a>
Expand Down Expand Up @@ -178,6 +178,9 @@
<li>
<a href="/docs/providers/scaleway/d/security_group.html">scaleway_security_group</a>
</li>
<li>
<a href="/docs/providers/scaleway/d/image.html">scaleway_image</a>
</li>
</ul>
</li>

Expand Down

0 comments on commit f69dec3

Please sign in to comment.