mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-09 15:43:53 -06:00
4ad825fe08
This means that two resources created by the same rule will get names which sort in the order they are created. The rest of the ID is still random base32 characters; we no longer set the bit values that denote UUIDv4. The length of the ID returned by PrefixedUniqueId is not changed by this commit; that way we don't break any resources where the underlying resource has a name length limit. Fixes #8143.
54 lines
1.5 KiB
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
|
|
}
|