github.com/chanzuckerberg/terraform@v0.11.12-beta1/helper/acctest/random.go (about) 1 package acctest 2 3 import ( 4 "bytes" 5 crand "crypto/rand" 6 "crypto/rsa" 7 "crypto/x509" 8 "crypto/x509/pkix" 9 "encoding/pem" 10 "fmt" 11 "math/big" 12 "math/rand" 13 "strings" 14 "time" 15 16 "golang.org/x/crypto/ssh" 17 ) 18 19 // Helpers for generating random tidbits for use in identifiers to prevent 20 // collisions in acceptance tests. 21 22 // RandInt generates a random integer 23 func RandInt() int { 24 reseed() 25 return rand.New(rand.NewSource(time.Now().UnixNano())).Int() 26 } 27 28 // RandomWithPrefix is used to generate a unique name with a prefix, for 29 // randomizing names in acceptance tests 30 func RandomWithPrefix(name string) string { 31 reseed() 32 return fmt.Sprintf("%s-%d", name, rand.New(rand.NewSource(time.Now().UnixNano())).Int()) 33 } 34 35 func RandIntRange(min int, max int) int { 36 reseed() 37 source := rand.New(rand.NewSource(time.Now().UnixNano())) 38 rangeMax := max - min 39 40 return int(source.Int31n(int32(rangeMax))) 41 } 42 43 // RandString generates a random alphanumeric string of the length specified 44 func RandString(strlen int) string { 45 return RandStringFromCharSet(strlen, CharSetAlphaNum) 46 } 47 48 // RandStringFromCharSet generates a random string by selecting characters from 49 // the charset provided 50 func RandStringFromCharSet(strlen int, charSet string) string { 51 reseed() 52 result := make([]byte, strlen) 53 for i := 0; i < strlen; i++ { 54 result[i] = charSet[rand.Intn(len(charSet))] 55 } 56 return string(result) 57 } 58 59 // RandSSHKeyPair generates a public and private SSH key pair. The public key is 60 // returned in OpenSSH format, and the private key is PEM encoded. 61 func RandSSHKeyPair(comment string) (string, string, error) { 62 privateKey, privateKeyPEM, err := genPrivateKey() 63 if err != nil { 64 return "", "", err 65 } 66 67 publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) 68 if err != nil { 69 return "", "", err 70 } 71 keyMaterial := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey))) 72 return fmt.Sprintf("%s %s", keyMaterial, comment), privateKeyPEM, nil 73 } 74 75 // RandTLSCert generates a self-signed TLS certificate with a newly created 76 // private key, and returns both the cert and the private key PEM encoded. 77 func RandTLSCert(orgName string) (string, string, error) { 78 template := &x509.Certificate{ 79 SerialNumber: big.NewInt(int64(RandInt())), 80 Subject: pkix.Name{ 81 Organization: []string{orgName}, 82 }, 83 NotBefore: time.Now(), 84 NotAfter: time.Now().Add(24 * time.Hour), 85 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 86 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 87 BasicConstraintsValid: true, 88 } 89 90 privateKey, privateKeyPEM, err := genPrivateKey() 91 if err != nil { 92 return "", "", err 93 } 94 95 cert, err := x509.CreateCertificate(crand.Reader, template, template, &privateKey.PublicKey, privateKey) 96 if err != nil { 97 return "", "", err 98 } 99 100 certPEM, err := pemEncode(cert, "CERTIFICATE") 101 if err != nil { 102 return "", "", err 103 } 104 105 return certPEM, privateKeyPEM, nil 106 } 107 108 func genPrivateKey() (*rsa.PrivateKey, string, error) { 109 privateKey, err := rsa.GenerateKey(crand.Reader, 1024) 110 if err != nil { 111 return nil, "", err 112 } 113 114 privateKeyPEM, err := pemEncode(x509.MarshalPKCS1PrivateKey(privateKey), "RSA PRIVATE KEY") 115 if err != nil { 116 return nil, "", err 117 } 118 119 return privateKey, privateKeyPEM, nil 120 } 121 122 func pemEncode(b []byte, block string) (string, error) { 123 var buf bytes.Buffer 124 pb := &pem.Block{Type: block, Bytes: b} 125 if err := pem.Encode(&buf, pb); err != nil { 126 return "", err 127 } 128 129 return buf.String(), nil 130 } 131 132 // Seeds random with current timestamp 133 func reseed() { 134 rand.Seed(time.Now().UTC().UnixNano()) 135 } 136 137 const ( 138 // CharSetAlphaNum is the alphanumeric character set for use with 139 // RandStringFromCharSet 140 CharSetAlphaNum = "abcdefghijklmnopqrstuvwxyz012346789" 141 142 // CharSetAlpha is the alphabetical character set for use with 143 // RandStringFromCharSet 144 CharSetAlpha = "abcdefghijklmnopqrstuvwxyz" 145 )