Merge branch 'feat/provider-scaleway-bootscript' of https://github.com/nicolai86/terraform into nicolai86-feat/provider-scaleway-bootscript

This commit is contained in:
James Nugent 2016-10-18 08:06:14 -05:00
commit 4ef3ab70f9
7 changed files with 499 additions and 0 deletions

View File

@ -0,0 +1,119 @@
package scaleway
import (
"fmt"
"regexp"
"github.com/hashicorp/terraform/helper/schema"
"github.com/scaleway/scaleway-cli/pkg/api"
)
func dataSourceScalewayBootscript() *schema.Resource {
return &schema.Resource{
Read: dataSourceScalewayBootscriptRead,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"name_filter": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"architecture": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
},
// Computed values.
"organization": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"public": &schema.Schema{
Type: schema.TypeBool,
Computed: true,
},
"boot_cmd_args": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"dtb": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"initrd": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"kernel": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}
func bootscriptDescriptionAttributes(d *schema.ResourceData, script api.ScalewayBootscript) error {
d.Set("architecture", script.Arch)
d.Set("organization", script.Organization)
d.Set("public", script.Public)
d.Set("boot_cmd_args", script.Bootcmdargs)
d.Set("dtb", script.Dtb)
d.Set("initrd", script.Initrd)
d.Set("kernel", script.Kernel)
d.SetId(script.Identifier)
return nil
}
func dataSourceScalewayBootscriptRead(d *schema.ResourceData, meta interface{}) error {
scaleway := meta.(*Client).scaleway
scripts, err := scaleway.GetBootscripts()
if err != nil {
return err
}
var isMatch func(api.ScalewayBootscript) bool
if name, ok := d.GetOk("name"); ok {
isMatch = func(s api.ScalewayBootscript) bool {
return s.Title == name.(string)
}
} else if nameFilter, ok := d.GetOk("name_filter"); ok {
architecture := d.Get("architecture")
exp, err := regexp.Compile(nameFilter.(string))
if err != nil {
return err
}
isMatch = func(s api.ScalewayBootscript) bool {
nameMatch := exp.MatchString(s.Title)
architectureMatch := true
if architecture != "" {
architectureMatch = architecture == s.Arch
}
return nameMatch && architectureMatch
}
}
var matches []api.ScalewayBootscript
for _, script := range *scripts {
if isMatch(script) {
matches = append(matches, script)
}
}
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 bootscriptDescriptionAttributes(d, matches[0])
}

View File

@ -0,0 +1,72 @@
package scaleway
import (
"fmt"
"regexp"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccScalewayDataSourceBootscript_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckScalewayBootscriptConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckBootscriptID("data.scaleway_bootscript.debug"),
resource.TestCheckResourceAttr("data.scaleway_bootscript.debug", "architecture", "x86_64"),
resource.TestCheckResourceAttr("data.scaleway_bootscript.debug", "public", "true"),
resource.TestMatchResourceAttr("data.scaleway_bootscript.debug", "kernel", regexp.MustCompile("4.5.7")),
),
},
},
})
}
func TestAccScalewayDataSourceBootscript_Filtered(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckScalewayBootscriptFilterConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckBootscriptID("data.scaleway_bootscript.debug"),
resource.TestCheckResourceAttr("data.scaleway_bootscript.debug", "architecture", "arm"),
resource.TestCheckResourceAttr("data.scaleway_bootscript.debug", "public", "true"),
),
},
},
})
}
func testAccCheckBootscriptID(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find bootscript data source: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("bootscript data source ID not set")
}
return nil
}
}
const testAccCheckScalewayBootscriptConfig = `
data "scaleway_bootscript" "debug" {
name = "x86_64 4.5.7 debug #3"
}
`
const testAccCheckScalewayBootscriptFilterConfig = `
data "scaleway_bootscript" "debug" {
architecture = "arm"
name_filter = "Rescue"
}
`

View File

@ -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])
}

View File

@ -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"
}
`

View File

@ -38,6 +38,11 @@ func Provider() terraform.ResourceProvider {
"scaleway_volume_attachment": resourceScalewayVolumeAttachment(),
},
DataSourcesMap: map[string]*schema.Resource{
"scaleway_bootscript": dataSourceScalewayBootscript(),
"scaleway_image": dataSourceScalewayImage(),
},
ConfigureFunc: providerConfigure,
}
}

View File

@ -0,0 +1,49 @@
---
layout: "scaleway"
page_title: "Scaleway: scaleway_bootscript"
sidebar_current: "docs-scaleway-datasource-bootscript"
description: |-
Get information on a Scaleway bootscript.
---
# scaleway\_bootscript
Use this data source to get the ID of a registered Bootscript for use with the
`scaleway_server` resource.
## Example Usage
```
data "scaleway_bootscript" "debug" {
architecture = "arm"
name_filter = "Rescue"
}
```
## Argument Reference
* `architecture` - (Optional) any supported Scaleway architecture, e.g. `x86_64`, `arm`
* `name_filter` - (Optional) Regexp to match Bootscript name by
* `name` - (Optional) Exact name of desired Bootscript
## Attributes Reference
`id` is set to the ID of the found Bootscript. In addition, the following attributes
are exported:
* `architecture` - architecture of the Bootscript, e.g. `arm` or `x86_64`
* `organization` - uuid of the organization owning this Bootscript
* `public` - is this a public bootscript
* `boot_cmd_args` - command line arguments used for booting
* `dtb` - path to Device Tree Blob detailing hardware information
* `initrd` - URL to initial ramdisk content
* `kernel` - URL to used kernel

View File

@ -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