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  )