terraform/helper/resource/id.go

54 lines
1.5 KiB
Go

package resource
import (
"crypto/rand"
"encoding/base32"
"fmt"
"strings"
"time"
)
const UniqueIdPrefix = `terraform-`
// Helper for a resource to generate a unique identifier w/ default prefix
func UniqueId() string {
return PrefixedUniqueId(UniqueIdPrefix)
}
// Helper for a resource to generate a unique identifier w/ given prefix
//
// After the prefix, the ID consists of a timestamp and 12 random base32
// characters. The timestamp means that multiple IDs created with the same
// prefix will sort in the order of their creation.
func PrefixedUniqueId(prefix string) string {
// Be precise to the level nanoseconds, but remove the dot before the
// nanosecond. We assume that the randomCharacters call takes at least a
// nanosecond, so that multiple calls to this function from the same goroutine
// will have distinct ordered timestamps.
timestamp := strings.Replace(
time.Now().UTC().Format("20060102150405.000000000"),
".",
"", 1)
// This uses 3 characters, so that the length of the unique ID is the same as
// it was before we added the timestamp prefix, which happened to be 23
// characters.
return fmt.Sprintf("%s%s%s", prefix, timestamp, randomCharacters(3))
}
func randomCharacters(n int) string {
// Base32 has 5 bits of information per character.
b := randomBytes(n * 8 / 5)
chars := strings.ToLower(
strings.Replace(
base32.StdEncoding.EncodeToString(b),
"=", "", -1))
// Trim extra characters.
return chars[:n]
}
func randomBytes(n int) []byte {
b := make([]byte, n)
rand.Read(b)
return b
}