github.com/bradfeehan/terraform@v0.7.0-rc3.0.20170529055808-34b45c5ad841/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  
    64  	publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
    65  	if err != nil {
    66  		return "", "", err
    67  	}
    68  	keyMaterial := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey)))
    69  	return fmt.Sprintf("%s %s", keyMaterial, comment), privateKeyPEM, nil
    70  }
    71  
    72  // RandTLSCert generates a self-signed TLS certificate with a newly created
    73  // private key, and returns both the cert and the private key PEM encoded.
    74  func RandTLSCert(orgName string) (string, string, error) {
    75  	template := &x509.Certificate{
    76  		SerialNumber: big.NewInt(int64(RandInt())),
    77  		Subject: pkix.Name{
    78  			Organization: []string{orgName},
    79  		},
    80  		NotBefore:             time.Now(),
    81  		NotAfter:              time.Now().Add(24 * time.Hour),
    82  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
    83  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    84  		BasicConstraintsValid: true,
    85  	}
    86  
    87  	privateKey, privateKeyPEM, err := genPrivateKey()
    88  	if err != nil {
    89  		return "", "", err
    90  	}
    91  
    92  	cert, err := x509.CreateCertificate(crand.Reader, template, template, &privateKey.PublicKey, privateKey)
    93  	if err != nil {
    94  		return "", "", err
    95  	}
    96  
    97  	certPEM, err := pemEncode(cert, "CERTIFICATE")
    98  	if err != nil {
    99  		return "", "", err
   100  	}
   101  
   102  	return certPEM, privateKeyPEM, nil
   103  }
   104  
   105  func genPrivateKey() (*rsa.PrivateKey, string, error) {
   106  	privateKey, err := rsa.GenerateKey(crand.Reader, 1024)
   107  	if err != nil {
   108  		return nil, "", err
   109  	}
   110  
   111  	privateKeyPEM, err := pemEncode(x509.MarshalPKCS1PrivateKey(privateKey), "RSA PRIVATE KEY")
   112  	if err != nil {
   113  		return nil, "", err
   114  	}
   115  
   116  	return privateKey, privateKeyPEM, nil
   117  }
   118  
   119  func pemEncode(b []byte, block string) (string, error) {
   120  	var buf bytes.Buffer
   121  	pb := &pem.Block{Type: block, Bytes: b}
   122  	if err := pem.Encode(&buf, pb); err != nil {
   123  		return "", err
   124  	}
   125  
   126  	return buf.String(), nil
   127  }
   128  
   129  // Seeds random with current timestamp
   130  func reseed() {
   131  	rand.Seed(time.Now().UTC().UnixNano())
   132  }
   133  
   134  const (
   135  	// CharSetAlphaNum is the alphanumeric character set for use with
   136  	// RandStringFromCharSet
   137  	CharSetAlphaNum = "abcdefghijklmnopqrstuvwxyz012346789"
   138  
   139  	// CharSetAlpha is the alphabetical character set for use with
   140  	// RandStringFromCharSet
   141  	CharSetAlpha = "abcdefghijklmnopqrstuvwxyz"
   142  )