Skip to content

Commit 903170d

Browse files
committed
provider/scaleway: add image data source
1 parent 1552c33 commit 903170d

4 files changed

Lines changed: 255 additions & 0 deletions

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package scaleway
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"regexp"
7+
8+
"github.com/hashicorp/terraform/helper/schema"
9+
"github.com/scaleway/scaleway-cli/pkg/api"
10+
)
11+
12+
func dataSourceScalewayImage() *schema.Resource {
13+
return &schema.Resource{
14+
Read: dataSourceScalewayImageRead,
15+
16+
Schema: map[string]*schema.Schema{
17+
"name": &schema.Schema{
18+
Type: schema.TypeString,
19+
Optional: true,
20+
ForceNew: true,
21+
Computed: true,
22+
},
23+
"name_filter": &schema.Schema{
24+
Type: schema.TypeString,
25+
Optional: true,
26+
ForceNew: true,
27+
},
28+
"architecture": &schema.Schema{
29+
Type: schema.TypeString,
30+
Required: true,
31+
ForceNew: true,
32+
},
33+
// Computed values.
34+
"organization": &schema.Schema{
35+
Type: schema.TypeString,
36+
Computed: true,
37+
},
38+
"public": &schema.Schema{
39+
Type: schema.TypeBool,
40+
Computed: true,
41+
},
42+
"creation_date": &schema.Schema{
43+
Type: schema.TypeString,
44+
Computed: true,
45+
},
46+
},
47+
}
48+
}
49+
50+
func scalewayImageAttributes(d *schema.ResourceData, img imageMatch) error {
51+
d.Set("architecture", img.imageDefinition.Arch)
52+
d.Set("organization", img.marketImage.Organization)
53+
d.Set("public", img.marketImage.Public)
54+
d.Set("creation_date", img.marketImage.CreationDate)
55+
d.Set("name", img.marketImage.Name)
56+
d.SetId(img.imageDefinition.ID)
57+
58+
return nil
59+
}
60+
61+
type imageMatch struct {
62+
marketImage api.MarketImage
63+
imageDefinition api.MarketLocalImageDefinition
64+
}
65+
66+
func dataSourceScalewayImageRead(d *schema.ResourceData, meta interface{}) error {
67+
scaleway := meta.(*Client).scaleway
68+
69+
images, err := scaleway.GetImages()
70+
log.Printf("[DEBUG] %#v", images)
71+
if err != nil {
72+
return err
73+
}
74+
75+
var isNameMatch = func(api.MarketImage) bool { return true }
76+
var isArchMatch = func(api.MarketLocalImageDefinition) bool { return true }
77+
78+
if name, ok := d.GetOk("name"); ok {
79+
isNameMatch = func(img api.MarketImage) bool {
80+
return img.Name == name.(string)
81+
}
82+
} else if nameFilter, ok := d.GetOk("name_filter"); ok {
83+
exp, err := regexp.Compile(nameFilter.(string))
84+
if err != nil {
85+
return err
86+
}
87+
88+
isNameMatch = func(img api.MarketImage) bool {
89+
return exp.MatchString(img.Name)
90+
}
91+
}
92+
93+
var architecture = d.Get("architecture").(string)
94+
if architecture != "" {
95+
isArchMatch = func(img api.MarketLocalImageDefinition) bool {
96+
return img.Arch == architecture
97+
}
98+
}
99+
100+
var matches []imageMatch
101+
for _, img := range *images {
102+
if !isNameMatch(img) {
103+
continue
104+
}
105+
106+
var imageDefinition *api.MarketLocalImageDefinition
107+
for _, version := range img.Versions {
108+
for _, def := range version.LocalImages {
109+
if isArchMatch(def) {
110+
imageDefinition = &def
111+
break
112+
}
113+
}
114+
}
115+
116+
if imageDefinition == nil {
117+
continue
118+
}
119+
matches = append(matches, imageMatch{
120+
marketImage: img,
121+
imageDefinition: *imageDefinition,
122+
})
123+
}
124+
125+
if len(matches) > 1 {
126+
return fmt.Errorf("The query returned more than one result. Please refine your query.")
127+
}
128+
if len(matches) == 0 {
129+
return fmt.Errorf("The query returned no result. Please refine your query.")
130+
}
131+
132+
return scalewayImageAttributes(d, matches[0])
133+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package scaleway
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform/helper/resource"
8+
"github.com/hashicorp/terraform/terraform"
9+
)
10+
11+
func TestAccScalewayDataSourceImage_Basic(t *testing.T) {
12+
resource.Test(t, resource.TestCase{
13+
PreCheck: func() { testAccPreCheck(t) },
14+
Providers: testAccProviders,
15+
Steps: []resource.TestStep{
16+
resource.TestStep{
17+
Config: testAccCheckScalewayImageConfig,
18+
Check: resource.ComposeTestCheckFunc(
19+
testAccCheckImageID("data.scaleway_image.ubuntu"),
20+
resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "architecture", "arm"),
21+
resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "public", "true"),
22+
),
23+
},
24+
},
25+
})
26+
}
27+
28+
func TestAccScalewayDataSourceImage_Filtered(t *testing.T) {
29+
resource.Test(t, resource.TestCase{
30+
PreCheck: func() { testAccPreCheck(t) },
31+
Providers: testAccProviders,
32+
Steps: []resource.TestStep{
33+
resource.TestStep{
34+
Config: testAccCheckScalewayImageFilterConfig,
35+
Check: resource.ComposeTestCheckFunc(
36+
testAccCheckImageID("data.scaleway_image.ubuntu"),
37+
resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "name", "Ubuntu Precise"),
38+
resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "architecture", "arm"),
39+
resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "public", "true"),
40+
),
41+
},
42+
},
43+
})
44+
}
45+
46+
func testAccCheckImageID(n string) resource.TestCheckFunc {
47+
return func(s *terraform.State) error {
48+
rs, ok := s.RootModule().Resources[n]
49+
if !ok {
50+
return fmt.Errorf("Can't find image data source: %s", n)
51+
}
52+
53+
if rs.Primary.ID == "" {
54+
return fmt.Errorf("image data source ID not set")
55+
}
56+
return nil
57+
}
58+
}
59+
60+
const testAccCheckScalewayImageConfig = `
61+
data "scaleway_image" "ubuntu" {
62+
name = "Ubuntu Precise"
63+
architecture = "arm"
64+
}
65+
`
66+
67+
const testAccCheckScalewayImageFilterConfig = `
68+
data "scaleway_image" "ubuntu" {
69+
name_filter = "Precise"
70+
architecture = "arm"
71+
}
72+
`

builtin/providers/scaleway/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func Provider() terraform.ResourceProvider {
4040

4141
DataSourcesMap: map[string]*schema.Resource{
4242
"scaleway_bootscript": dataSourceScalewayBootscript(),
43+
"scaleway_image": dataSourceScalewayImage(),
4344
},
4445

4546
ConfigureFunc: providerConfigure,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
layout: "scaleway"
3+
page_title: "Scaleway: scaleway_image"
4+
sidebar_current: "docs-scaleway-datasource-image"
5+
description: |-
6+
Get information on a Scaleway image.
7+
---
8+
9+
# scaleway\_image
10+
11+
Use this data source to get the ID of a registered Image for use with the
12+
`scaleway_server` resource.
13+
14+
## Example Usage
15+
16+
```
17+
data "scaleway_image" "ubuntu" {
18+
architecture = "arm"
19+
name = "Ubuntu Precise"
20+
}
21+
22+
resource "scaleway_server" "base" {
23+
name = "test"
24+
image = "${data.scaleway_image.ubuntu.id}"
25+
type = "C1"
26+
}
27+
```
28+
29+
## Argument Reference
30+
31+
* `architecture` - (Required) any supported Scaleway architecture, e.g. `x86_64`, `arm`
32+
33+
* `name_filter` - (Optional) Regexp to match Image name by
34+
35+
* `name` - (Optional) Exact name of desired Image
36+
37+
## Attributes Reference
38+
39+
`id` is set to the ID of the found Image. In addition, the following attributes
40+
are exported:
41+
42+
* `architecture` - architecture of the Image, e.g. `arm` or `x86_64`
43+
44+
* `organization` - uuid of the organization owning this Image
45+
46+
* `public` - is this a public bootscript
47+
48+
* `creation_date` - date when image was created
49+

0 commit comments

Comments
 (0)