provider/random: random_id resource
This resource generates a cryptographically-strong set of bytes and provides them as base64, hexadecimal and decimal string representations. It is intended to be used for generating unique ids for resources elsewhere in the configuration, and thus the "keepers" would be set to any ForceNew attributes of the target resources, so that a new id is generated each time a new resource is generated.
This commit is contained in:
parent
3e34ddbf38
commit
b1de477691
|
@ -11,7 +11,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
Schema: map[string]*schema.Schema{},
|
Schema: map[string]*schema.Schema{},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
//"random_id": resourceId(),
|
"random_id": resourceId(),
|
||||||
//"random_shuffle": resourceShuffle(),
|
//"random_shuffle": resourceShuffle(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
`
|
Loading…
Reference in New Issue