diff --git a/builtin/providers/scaleway/data_source_scaleway_image.go b/builtin/providers/scaleway/data_source_scaleway_image.go new file mode 100644 index 000000000..5d9cb7fce --- /dev/null +++ b/builtin/providers/scaleway/data_source_scaleway_image.go @@ -0,0 +1,133 @@ +package scaleway + +import ( + "fmt" + "log" + "regexp" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/scaleway/scaleway-cli/pkg/api" +) + +func dataSourceScalewayImage() *schema.Resource { + return &schema.Resource{ + Read: dataSourceScalewayImageRead, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + "name_filter": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "architecture": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + // Computed values. + "organization": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "public": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + }, + "creation_date": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func scalewayImageAttributes(d *schema.ResourceData, img imageMatch) error { + d.Set("architecture", img.imageDefinition.Arch) + d.Set("organization", img.marketImage.Organization) + d.Set("public", img.marketImage.Public) + d.Set("creation_date", img.marketImage.CreationDate) + d.Set("name", img.marketImage.Name) + d.SetId(img.imageDefinition.ID) + + return nil +} + +type imageMatch struct { + marketImage api.MarketImage + imageDefinition api.MarketLocalImageDefinition +} + +func dataSourceScalewayImageRead(d *schema.ResourceData, meta interface{}) error { + scaleway := meta.(*Client).scaleway + + images, err := scaleway.GetImages() + log.Printf("[DEBUG] %#v", images) + if err != nil { + return err + } + + var isNameMatch = func(api.MarketImage) bool { return true } + var isArchMatch = func(api.MarketLocalImageDefinition) bool { return true } + + if name, ok := d.GetOk("name"); ok { + isNameMatch = func(img api.MarketImage) bool { + return img.Name == name.(string) + } + } else if nameFilter, ok := d.GetOk("name_filter"); ok { + exp, err := regexp.Compile(nameFilter.(string)) + if err != nil { + return err + } + + isNameMatch = func(img api.MarketImage) bool { + return exp.MatchString(img.Name) + } + } + + var architecture = d.Get("architecture").(string) + if architecture != "" { + isArchMatch = func(img api.MarketLocalImageDefinition) bool { + return img.Arch == architecture + } + } + + var matches []imageMatch + for _, img := range *images { + if !isNameMatch(img) { + continue + } + + var imageDefinition *api.MarketLocalImageDefinition + for _, version := range img.Versions { + for _, def := range version.LocalImages { + if isArchMatch(def) { + imageDefinition = &def + break + } + } + } + + if imageDefinition == nil { + continue + } + matches = append(matches, imageMatch{ + marketImage: img, + imageDefinition: *imageDefinition, + }) + } + + if len(matches) > 1 { + return fmt.Errorf("The query returned more than one result. Please refine your query.") + } + if len(matches) == 0 { + return fmt.Errorf("The query returned no result. Please refine your query.") + } + + return scalewayImageAttributes(d, matches[0]) +} diff --git a/builtin/providers/scaleway/data_source_scaleway_image_test.go b/builtin/providers/scaleway/data_source_scaleway_image_test.go new file mode 100644 index 000000000..3c11b9e22 --- /dev/null +++ b/builtin/providers/scaleway/data_source_scaleway_image_test.go @@ -0,0 +1,72 @@ +package scaleway + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccScalewayDataSourceImage_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckScalewayImageConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckImageID("data.scaleway_image.ubuntu"), + resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "architecture", "arm"), + resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "public", "true"), + ), + }, + }, + }) +} + +func TestAccScalewayDataSourceImage_Filtered(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckScalewayImageFilterConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckImageID("data.scaleway_image.ubuntu"), + resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "name", "Ubuntu Precise"), + resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "architecture", "arm"), + resource.TestCheckResourceAttr("data.scaleway_image.ubuntu", "public", "true"), + ), + }, + }, + }) +} + +func testAccCheckImageID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find image data source: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("image data source ID not set") + } + return nil + } +} + +const testAccCheckScalewayImageConfig = ` +data "scaleway_image" "ubuntu" { + name = "Ubuntu Precise" + architecture = "arm" +} +` + +const testAccCheckScalewayImageFilterConfig = ` +data "scaleway_image" "ubuntu" { + name_filter = "Precise" + architecture = "arm" +} +` diff --git a/builtin/providers/scaleway/provider.go b/builtin/providers/scaleway/provider.go index 9adf314e1..259d83182 100644 --- a/builtin/providers/scaleway/provider.go +++ b/builtin/providers/scaleway/provider.go @@ -40,6 +40,7 @@ func Provider() terraform.ResourceProvider { DataSourcesMap: map[string]*schema.Resource{ "scaleway_bootscript": dataSourceScalewayBootscript(), + "scaleway_image": dataSourceScalewayImage(), }, ConfigureFunc: providerConfigure, diff --git a/website/source/docs/providers/scaleway/d/image.html.markdown b/website/source/docs/providers/scaleway/d/image.html.markdown new file mode 100644 index 000000000..101da8f9b --- /dev/null +++ b/website/source/docs/providers/scaleway/d/image.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "scaleway" +page_title: "Scaleway: scaleway_image" +sidebar_current: "docs-scaleway-datasource-image" +description: |- + Get information on a Scaleway image. +--- + +# scaleway\_image + +Use this data source to get the ID of a registered Image for use with the +`scaleway_server` resource. + +## Example Usage + +``` +data "scaleway_image" "ubuntu" { + architecture = "arm" + name = "Ubuntu Precise" +} + +resource "scaleway_server" "base" { + name = "test" + image = "${data.scaleway_image.ubuntu.id}" + type = "C1" +} +``` + +## Argument Reference + +* `architecture` - (Required) any supported Scaleway architecture, e.g. `x86_64`, `arm` + +* `name_filter` - (Optional) Regexp to match Image name by + +* `name` - (Optional) Exact name of desired Image + +## Attributes Reference + +`id` is set to the ID of the found Image. In addition, the following attributes +are exported: + +* `architecture` - architecture of the Image, e.g. `arm` or `x86_64` + +* `organization` - uuid of the organization owning this Image + +* `public` - is this a public bootscript + +* `creation_date` - date when image was created +