diff --git a/builtin/providers/random/provider.go b/builtin/providers/random/provider.go index 999fe19eff..2714823814 100644 --- a/builtin/providers/random/provider.go +++ b/builtin/providers/random/provider.go @@ -11,7 +11,7 @@ func Provider() terraform.ResourceProvider { Schema: map[string]*schema.Schema{}, ResourcesMap: map[string]*schema.Resource{ - //"random_id": resourceId(), + "random_id": resourceId(), //"random_shuffle": resourceShuffle(), }, } diff --git a/builtin/providers/random/resource_id.go b/builtin/providers/random/resource_id.go new file mode 100644 index 0000000000..9bb36b9ef9 --- /dev/null +++ b/builtin/providers/random/resource_id.go @@ -0,0 +1,76 @@ +package random + +import ( + "crypto/rand" + "encoding/base64" + "encoding/hex" + "fmt" + "math/big" + + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceId() *schema.Resource { + return &schema.Resource{ + Create: CreateID, + Read: stubRead, + Delete: stubDelete, + + Schema: map[string]*schema.Schema{ + "keepers": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + }, + + "byte_length": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + + "b64": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "hex": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "dec": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func CreateID(d *schema.ResourceData, meta interface{}) error { + + byteLength := d.Get("byte_length").(int) + bytes := make([]byte, byteLength) + + n, err := rand.Reader.Read(bytes) + if n != byteLength { + return fmt.Errorf("generated insufficient random bytes") + } + if err != nil { + return fmt.Errorf("error generating random bytes: %s", err) + } + + b64Str := base64.RawURLEncoding.EncodeToString(bytes) + hexStr := hex.EncodeToString(bytes) + + int := big.Int{} + int.SetBytes(bytes) + decStr := int.String() + + d.SetId(b64Str) + d.Set("b64", b64Str) + d.Set("hex", hexStr) + d.Set("dec", decStr) + + return nil +} diff --git a/builtin/providers/random/resource_id_test.go b/builtin/providers/random/resource_id_test.go new file mode 100644 index 0000000000..ed6b8af8d3 --- /dev/null +++ b/builtin/providers/random/resource_id_test.go @@ -0,0 +1,58 @@ +package random + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccResourceID(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccResourceIDConfig, + Check: resource.ComposeTestCheckFunc( + testAccResourceIDCheck("random_id.foo"), + ), + }, + }, + }) +} + +func testAccResourceIDCheck(id string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[id] + if !ok { + return fmt.Errorf("Not found: %s", id) + } + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + b64Str := rs.Primary.Attributes["b64"] + hexStr := rs.Primary.Attributes["hex"] + decStr := rs.Primary.Attributes["dec"] + + if got, want := len(b64Str), 6; got != want { + return fmt.Errorf("base64 string length is %d; want %d", got, want) + } + if got, want := len(hexStr), 8; got != want { + return fmt.Errorf("hex string length is %d; want %d", got, want) + } + if len(decStr) < 1 { + return fmt.Errorf("decimal string is empty; want at least one digit") + } + + return nil + } +} + +const testAccResourceIDConfig = ` +resource "random_id" "foo" { + byte_length = 4 +} +`